2009-03-20 9 views
10

Mam aplikacji XBAP z następującą kontrolą użytkownika:Jak pobrać ciąg z zasobu do przypisania w sekcji WPF zasobów w XAML

<UserControl x:Class="XXX.UsersGrid" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Height="Auto" Width="Auto"> 

     <UserControl.Resources> 
      <DataTemplate x:Key="UpArrowUsers"> 
       <DockPanel> 
        <TextBlock Text="xxUser" x:Name="upArrowUsersHeader" HorizontalAlignment="Center"></TextBlock> 
        <Path x:Name="arrow" StrokeThickness = "1" Fill= "gray" Data= "M 5,10 L 15,10 L 10,5 L 5,10"/> 
       </DockPanel> 
      </DataTemplate> 
    </UserControl> 
    ... 

Teraz chcę, aby pobrać ciąg „xxUser” z pliku RESX który jest osadzony jako zasób w aplikacji. Jak to zrobić?

Odpowiedz

3

Żadna z tych odpowiedzi nie jest zbliżona do tego, co chcesz. Zacznę od przeczytania o lokalizacji w WPF. Przekonasz się, że jeśli robisz lokalizację za pomocą WPF, będziesz potrzebował x: Uid zdefiniowany dla każdego węzła w twojej aplikacji.

http://msdn.microsoft.com/en-us/library/ms788718.aspx

+7

Cieszę się, że pomogło to w stworzeniu oryginalnego plakatu, ale zazwyczaj celem forum jest dodanie czegoś do oficjalnych dokumentów. Tylko moje 2 centy. – greenoldman

0

Nie wiem, czy można to zrobić bezpośrednio w XAML, ale jeśli napiszesz własną klasę opakowania wokół ResourceManager i użyjesz jej zamiast tego. Zauważ, że klasa dziedziczy z TextBlock:

public class ResourceContentTextBlock : TextBlock 
{ 
    public string ResourceName 
    { 
     set 
     { 
      this.Text = Properties.Resources.ResourceManager.GetString(value); 
     } 
    } 
} 

Następnie można użyć ResourceContentTextBlock w XAML gdziekolwiek byś inaczej używać TextBlock:

<Window x:Class="WpfApplication3.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:client="clr-namespace:WpfApplication3" 
    > 
     <client:ResourceContentTextBlock ResourceName="String1" /> 
</Window> 
+0

Jestem zdezorientowany tym. Co tu się dzieje? Dlaczego zdefiniowałeś setera, ale bez efektu? I czy literały "String1" w C# i XAML mają jakieś połączenie? Proszę o wyjaśnienie. –

+0

Masz rację - muszę przyznać, że jest to straszna odpowiedź z kilkoma błędami. Zrobiłem kilka szans, aby to poprawić, ale jest to kłopotliwe rozwiązanie. Chodzi o to, że właściwość ResourceName jest ustawiona na "String1" w XAML. ResourceContentTextBlock używa tej wartości do pobrania zlokalizowanego ciągu znaków z zasobów i aktualizuje właściwość Text odziedziczonego TextBox. Dlatego nie ma potrzeby uzyskiwania własności. –

5

Tworzenie statycznej klasy, która sprawia, że ​​zasoby dostępne jako właściwości:

public static class Resources 
{ 
    public string Resource 
    { 
     return Properties.Resources.ResourceManager.GetString("Resource"); 
    } 
} 

Następnie można powiązać swój TextBox do tego:

<TextBlock Text="{Binding Source={x:Static local:Resources}, Path=Resource}" x:Name="upArrowUsersHeader" HorizontalAlignment="Center" 
    xmlns:local="clr-namespace:MY_NAMESPACE;assembly=MY_ASSEMBLY"> 
42

udało mi się to zrobić w programie z:

<TextBlock VerticalAlignment="Center" Margin="3" 
      Text="{x:Static prop:Resources.OpenButton}" 
      Visibility="{Binding Source={x:Static prop:Settings.Default}, Path=ShowButtonText, Converter={StaticResource BoolToVis}}"></TextBlock> 

miałem również zawierać nazw .Properties w moim XAML, tak:

xmlns:prop="clr-namespace:MyProjectNamespace.Properties" 

Pozwoliło mi to nie tylko wykorzystać zasoby ciągów, które zdefiniowałem dla mojego projektu na potrzeby globalizacji, ale byłem również w stanie powiązać (dwukierunkowo) ustawienia mojej aplikacji. Pozwoliło mi to bardzo łatwo zapamiętać położenie, rozmiar itp. Okna. Jak widać, użyj Ustawień. dla ustawień i Zasobów. dla zasobów.

Tak jak wspomniała Steven, myślę, że "oficjalna" droga lub "najlepsza" droga to trzymać x: Uid we wszystkim, co chcesz globalizować, ale ja tego nie zrobiłem i zadziałało bez problemów. Sądzę, że funkcja x: Uid jest w większości przypadków wymagana, jeśli używasz automatycznych narzędzi lub zmieniasz zadanie tłumaczenia tak jak w przypadku dużego projektu. Po prostu zrobiłem wszystkie swoje rzeczy ręcznie w VS, więc może było dobrze.

Ben

+0

Dziękuję bardzo za tę pomocną i pomocną odpowiedź. Bardzo mi to pomogło - był to ostatni brakujący element w moim projekcie :-) Miałem tylko pomyłki z Zasobami - trzeba je było zdefiniować poprzez Właściwości projektu, a nie "Dodaj -> Nowy Przedmiot -> Zasoby", dobrze? – greenoldman

9

Dwa więcej dodatkowych punktów, że zapomniałem wspomnieć powyżej w „Udało mi się to zrobić ...”:

  1. Nie trzeba zawijać obiekt Properties.Resources w swoim własnym. Możesz uzyskać do niego bezpośredni dostęp, tak jak to zrobiłem w powyższym przykładzie. Myślę, że owinięcie obiektu jest sposobem uzyskania tego samego wyniku, o którym mówię w drugim punkcie.
  2. Domyślnie pliki zasobów są tworzone z "ResXFileCodeGenerator". To czyni je wewnętrznymi, gdy generuje plik kodu, więc xaml nie może uzyskać do niego dostępu. Musisz zmienić to na "PublicResXFileCodeGenerator", który generuje klasy publiczne.Możesz to zmienić, klikając plik zasobów w eksploratorze rozwiązań i edytując właściwość "Własne narzędzie".

(przepraszam, nie mogłem edytować powyższego posta, bo był tymczasowy członek w tym czasie).

+3

ad.2. Jest to typowe zaniedbanie (niespodzianka), VS pozwala po prostu przejść na "publiczny" (pasek "modyfikator dostępu" na pasku narzędzi). Nie jest potrzebne narzędzie innej firmy. – greenoldman

+0

Dzięki za poradę, próbowałem dowiedzieć się, dlaczego moje zasoby zostały ustawione na wewnętrzne i nie można ich użyć ... dlaczego nie jest to pole rozwijane w Visual Studio? : \ – John

4

Jak Ben powiedział i znalazłem an another tutorial. Wartość access modifier z Resources.resx powinna zostać zmieniona z Internal na Public. Wiele razy zawiodłem i po zmianie access modifier na Public, to działa.

Powiązane problemy