多语言 WPF 应用程序:不适用于组合框

本文关键字:适用于 组合 不适用 语言 WPF 应用程序 | 更新日期: 2023-09-27 18:35:20

我在这里使用Andre的答案创建了一个多语言WPF应用程序。我像这样绑定文本

<TextBlock Text="{DynamicResource Create}"/>

并且可以在运行时从英语切换到法语 - 很好!但是,这不适用于 ItemsSource。例如,我有一个应该显示所有可用语言的组合框:

<ComboBox ItemsSource="{Binding AllLanguages, Source={StaticResource Locator}}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{DynamicResource LanguageId}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

像这样设置,组合框不显示任何文本。如果我将文本块内部的文本设置为 Text={LanguageId} ,我会看到 LanguageId 'eng'、'fr' 等,因此绑定有效。

使用转换器时:

<TextBlock Text="{Binding LanguageId, Converter={StaticResource DynamicResourceConverter}"/>

语言显示为"英语"和"法语"。但是,当我切换语言时,不会再次调用转换器,也不会更新语言名称 - 因此这不是真正的解决方法。

我非常感谢有关原因以及如何解决此问题的提示。

多语言 WPF 应用程序:不适用于组合框

我将首先解释为什么有些事情不起作用。

    ....
    <DataTemplate>
        <TextBlock Text="{DynamicResource LanguageId}"/>
    </DataTemplate>
    ....

这是Text="{DynamicResource ResourceKey='LanguageId'}"的简写,它是一个静态字符串文字,不涉及任何绑定。

如果以下内容可用,那就太好了,但不幸的是是不可能的,因为绑定的目标不是DependancyProperty

    ....
    <DataTemplate>
        <TextBlock Text="{DynamicResource ResourceKey={Binding LanguageId}}"/>
    </DataTemplate>
    ....

您的解决方法已接近。 我的建议是尝试以下方法:-

    ....
    <DataTemplate>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource DynamicResourceConverter}">
                    <Binding Path="LanguageId"/>
                    <Binding Path="SomeOtherPropertyThatChangesWhenLanguageIsSwitched" Source="{StaticResource Locator}"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
    ....

您将需要扩展DynamicResourceConverter,现在还要实现IMultiValueConverter。 在MultiBinding方案中,如果任一绑定表达式发生更改,则会再次调用转换器。 您将编写Converter,使其仅在提供的对象数组values[0]上运行,因为不需要第二个值,并且仅提供再次调用转换器的触发器。

    public class DynamicResourceConverter: IValueConverter, IMultiValueConverter
    {
        ....
        // original converter implementation for IValueConverter
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ....
        }
        // newly added converter implementation for IMultiValueConverter
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            //call the original converter method with one value (assuming you've checked the array has at least one item!!
            return Convert(values[0], targetType, parameter, culture)
        }
        ....
    }