【问题标题】:How to change the CultureInfo of a Converter?如何更改转换器的 CultureInfo?
【发布时间】:2009-05-29 16:58:07
【问题描述】:

我有一个显示用户控件 DP 的一些文本的用户控件。为此,使用了转换器。我知道文化参数是“en-US”文化,除非您在绑定的 ConverterCulture 值或 xml:lang 属性中指定不同的文化。

但是我怎样才能从 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>

【问题讨论】:

    标签: .net wpf localization


    【解决方案1】:

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

    TheDuke 关于多个 xml:lang 属性的错误。虽然您确实只有 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 代码隐藏:

    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 添加了一个单例转换器,并重命名了一些命名空间,因此如果您正在执行直接剪切/粘贴,则可能需要将其改回。

    【讨论】:

    • 感谢 micahtan!您的解决方案完全符合我的要求。这么晚才回复很抱歉。我去过“nb-NO”几天了。
    【解决方案2】:

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

    这是我的 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,它允许您在更新字符串时将 CultureInfo 字符串传递给 UserControl UserControl 创建一个可以存储在成员变量中的 CultureInfo 对象,并更新 CultureName DependancyProperty UserControl 中的 TextBlock 绑定到。

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

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

    【讨论】:

    • 嗯,这种帮助,但我想对我的 UserControl 中使用的 Converter 对象使用不同的文化。我可以将用户控件本身作为转换器参数传递,然后在 ConvertTo 函数中从中获取 DP。但我宁愿不使用任何转换器参数。
    • 如果你能想办法存储静态成员变量中的 CultureInfo,然后您可以使用它为转换器提供不同的文化。
    • @micahtan:感谢您的澄清,目前无法评论您的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多