Как изменить CultureInfo конвертера? - PullRequest
1 голос
/ 25 мая 2009

У меня есть UserControl, который отображает некоторый текст DP элемента UserControl. Для этого используется конвертер. Я понимаю, что параметр культура - это культура "en-US", если вы не укажете другую культуру в значении ConverterCulture для привязки или атрибута xml: lang.

Но как я могу перейти на культуру вне UserControl ???

Это мой UserControl:

<UserControl x:Class="CultInfoConverter.MyUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:CultInfoConverter"
    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    Tag="{x:Null}">
    <UserControl.Resources>
        <my:MyConverter x:Key="MyConverter" />
    </UserControl.Resources>
    <StackPanel Orientation="Horizontal" >
        <TextBlock Margin="8">My converter culture is</TextBlock>
        <TextBlock FontWeight="Bold" Text="{Binding Tag, Converter={StaticResource MyConverter}}" />
    </StackPanel>
</UserControl>

В демонстрационных целях конвертер просто возвращает имя передаваемой ему информации о культуре:

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return culture.Name;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

В моем окне у меня есть два экземпляра пользовательского элемента управления, и каждый из них должен отображать свою культуру. Но оба просто показывают стандарт "en-US".

<Window x:Class="CultInfoConverter.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    xmlns:my="clr-namespace:CultInfoConverter">
    <StackPanel>
        <TextBlock Margin="8">using xml:lang="de-DE"</TextBlock>
        <my:MyUserControl xml:lang="de-DE"/>
        <TextBlock Margin="8">using xml:lang="fr-FR"</TextBlock>
        <my:MyUserControl xml:lang="fr-FR"/>
    </StackPanel>
</Window>

Ответы [ 2 ]

3 голосов
/ 29 мая 2009

Причина, по которой ваш пример не работает, заключается в том, что вы устанавливаете свойство xml: lang после того, как MyUserObject уже создан. TextBlock (и Binding, и Converter) уже созданы с использованием языка по умолчанию, то есть en-US.

TheDuke неверен в отношении нескольких атрибутов xml: lang. Хотя это правда, что у вас есть только 1 поток пользовательского интерфейса, и у него есть только 1 культура, каждому FrameworkElements разрешен собственный xml: lang Чтобы проверить это, установите для вашего атрибута xml: lang в вашем XAML MyUserControl (в вашем первом листинге кода) значение de-DE. Вы должны увидеть, что de-DE теперь появляется дважды жирным шрифтом.

Чтобы решить эту проблему, необходимо настроить привязку данных ПОСЛЕ MyUserControl создан и установлен атрибут Language / xml: lang. Я сделал быстрый тест, добавив DataBinding в событие Loaded MyUserControl. Это дает вам ожидаемые результаты (de-DE в первой строке, fr-Fr во второй).

альтернативный текст http://img35.imageshack.us/img35/4588/howtochangetheculturein.png

Листинг MyControl XAML:

<UserControl
    x:Class="WPFCultureTester.MyUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFCultureTester"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Tag="{x:Null}"
    Loaded="UserControl_Loaded">
    <StackPanel Orientation="Horizontal" >
        <TextBlock Margin="8">My converter culture is</TextBlock>
        <TextBlock x:Name="foo" FontWeight="Bold" />
    </StackPanel>
</UserControl>

MyControl Code-Behind:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WPFCultureTester
{
    /// <summary>
    /// Interaction logic for MyUserControl.xaml
    /// </summary>
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.foo.SetBinding(
                TextBlock.TextProperty,
                new Binding("") { Converter = CultInfoConverter.Converter });
        }
    }
}

Кстати, я позволил себе добавить одноэлементный конвертер в CultInfoConverter и переименовать некоторые пространства имен, поэтому вам, возможно, придется изменить его обратно, если вы делаете прямую вырезку / вставку.

0 голосов
/ 25 мая 2009

Я не эксперт по глобализации, на самом деле я не думаю, что когда-либо пробовал, но надеюсь, что это поможет.

Вот мой UserControl.xaml

<UserControl x:Class="Tab_Question.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="30">
<Grid>
    <TextBlock Text="{Binding Path=CultureName, FallbackValue=bindingError}" />
</Grid>

Вот код, стоящий за UserControl.cs

    public partial class UserControl1 : UserControl
{
    public static DependencyProperty CultureStringProperty =
        DependencyProperty.RegisterAttached("Culture", typeof(String), typeof(UserControl1));

    public static DependencyProperty CultureNameProperty =
        DependencyProperty.Register("CultureName", typeof(String), typeof(UserControl1));

    public String CultureString
    {
        get
        {
            return (String)GetValue(UserControl1.CultureStringProperty);
        }
        set
        {
            if (CultureString != value)
            {
                SetValue(UserControl1.CultureStringProperty, value);
                DoSomethingWithCulture();
            }
        }
    }

    private void DoSomethingWithCulture()
    {
        // Good to continue
        CultureInfo newCulture = CultureInfo.GetCultureInfo(CultureString);
        SetValue(UserControl1.CultureNameProperty, newCulture.Name);
    }

    public UserControl1()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

И, наконец, вот Window.xaml

<Window
x:Class="Tab_Question.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Tab_Question"
Title="Window1" Height="300" Width="300">
<StackPanel>
    <local:UserControl1 CultureString="en-us" />
    <local:UserControl1 CultureString="en-gb" />
</StackPanel>

Я постараюсь объяснить, что я сделал, надеюсь, это ответит на вопрос.

Я установил прикрепленный DependencyProperty в UserControl, который позволяет передавать строку CultureInfo в UserControl при обновлении строки. UserControl создает объект CultureInfo, который можно сохранить в переменной члена, и обновляет объект CultureName DependancyProperty, который TextBlock в UserControl привязывается к.

Я не уверен, почему заданный вами атрибут XmlLang не работает, но подозреваю, что он как-то связан с потоком пользовательского интерфейса, который может иметь только один язык.

Я знаю, что это не соответствует предоставленному вами примеру кода, но я надеюсь, что он предоставит вам стартовую площадку для изменения и адаптации.

Ben

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...