如何改变Converter的CultureInfo?

时间:2009-05-25 12:12:52

标签: .net wpf localization

我有一个UserControl,显示UserControl的DP的一些文本。为此,使用转换器。我理解culture参数是“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 个答案:

答案 0 :(得分:3)

您的示例不起作用的原因是您在构建MyUserObject之后设置了xml:lang属性。 TextBlock(和Binding和Converter)已经使用默认语言创建,即en-US。

关于多个xml:lang属性的TheDuke不正确。虽然这是真的,你只有1个UI线程,它只有1个文化,each FrameworkElements is allowed it's own xml:lang。要对此进行测试,请将MyUserControl XAML(在您的第一个代码清单中)中的xml:lang属性设置为de-DE。您应该看到de-DE现在以粗体显示两次。

要解决此问题,您必须设置DataBinding AFTER MyUserControl已构建且已设置Language / xml:lang属性。我通过在MyUserControl的Loaded事件中添加DataBinding进行了快速测试。这给你的结果我认为你期待(第一行是de-DE,第二行是fr-Fr)。

alt text 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添加了一个单例转换器,并重命名了一些命名空间,所以如果你做直接剪切/粘贴,你可能不得不改回它。

答案 1 :(得分:0)

我不是全球化专家,事实上我认为我没有尝试过,但希望这会有所帮助。

这是我的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>

我会尝试解释我所做的事情,希望它能回答这个问题。

我在UserControl上设置了一个附加的DependencyProperty,它允许您在更新String时将CultureInfo字符串传递给UserControl,UserControl创建一个可以存储在成员变量中的CultureInfo对象,并更新CultureName DependancyProperty, UserControl中的TextBlock绑定到。

我不确定为什么设置你尝试的XmlLang属性不起作用,但怀疑它与UI线程只能有一种语言有关。

我知道这与您提供的示例代码不符,但我希望它为您提供修改和改编的起点。