Как получить строку из ресурса для назначения в разделе ресурсов WPF в xaml - PullRequest
10 голосов
/ 20 марта 2009

У меня есть приложение XBAP со следующим пользовательским контролем:

  <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>
    ...

Теперь я хочу получить строку "xxUser" из файла resx, который встраивается как ресурс в приложение. Как мне этого добиться?

Ответы [ 6 ]

43 голосов
/ 31 января 2010

Я смог сделать это в программе с:

<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>

Мне также пришлось включить пространство имен .Properties в мой xaml, например:

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

Это позволило мне не только использовать строковые ресурсы, которые я определил для своего проекта для глобализации, но я также смог привязать (два способа) к настройкам моего приложения. Это позволило мне очень легко запомнить положение окна, размер и т. Д. Как видите, используйте Настройки. для настроек и ресурсов. за ресурсы.

Как уже упоминал Стивен, я думаю, что «официальный» или «лучший» способ - это использовать x: Uid для всего, что вы хотите глобализировать, но я этого не сделал, и это сработало без проблем. Я думаю, что x: Uid обычно требуется, если вы используете автоматизированные инструменты или разбиваете задачу перевода, как в большом проекте. Я просто сделал все свои вещи вручную в VS, так что, возможно, все было в порядке.

Ben

9 голосов
/ 31 января 2010

Еще два дополнительных момента, которые я забыл упомянуть выше в «Я смог сделать это ...»:

  1. Вам не нужно оборачивать объект Properties.Resources своим собственным. Вы можете получить к нему доступ напрямую, как я сделал в моем примере выше. Я думаю, что обертывание объекта - это способ получить тот же результат, который я обсуждаю во втором пункте.
  2. По умолчанию файлы ресурсов создаются с помощью ResXFileCodeGenerator. Это делает их внутренними, когда он генерирует файл кода, поэтому xaml не может получить к нему доступ. Вы должны изменить это на « PublicResXFileCodeGenerator », который генерирует публичные классы. Это можно изменить, щелкнув файл ресурса в обозревателе решений и изменив свойство «Пользовательский инструмент».

(извините, я не мог редактировать свой пост, потому что я был временным участником в то время.)

5 голосов
/ 02 апреля 2013

Как сказал Бен , и я нашел другой учебник . access modifier из Resources.resx следует изменить с Internal на Public. Я много раз терпел неудачу, и после изменения access modifier на Public он работает.

5 голосов
/ 20 марта 2009

Создайте статический класс, который делает ресурсы доступными в виде свойств:

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

Затем вы можете привязать свой TextBox к этому:

<TextBlock Text="{Binding Source={x:Static local:Resources}, Path=Resource}" x:Name="upArrowUsersHeader" HorizontalAlignment="Center"
   xmlns:local="clr-namespace:MY_NAMESPACE;assembly=MY_ASSEMBLY">
3 голосов
/ 20 марта 2009

Ни один из этих ответов не близок к тому, что вы хотите. Я бы начал с чтения о локализации в WPF. Вы обнаружите, что если вы делаете локализацию с WPF, вам нужно, чтобы x: Uid определялся на каждом узле вашего приложения.

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

0 голосов
/ 20 марта 2009

Я не знаю, можно ли это сделать напрямую в XAML, но если вы напишите свой собственный класс-оболочку для ResourceManager и будете использовать его вместо этого. Обратите внимание, что класс наследуется от TextBlock:

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

Затем вы можете использовать ResourceContentTextBlock в вашем XAML везде, где вы в противном случае использовали бы 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>
...