【问题标题】:Using placeholders in XAML for WPF Localization Extension在 XAML 中使用占位符进行 WPF 本地化扩展
【发布时间】:2016-08-24 12:32:59
【问题描述】:

我在我的程序中使用 WPF 本地化扩展。 为了减少类似资源的数量(如“长度以米为单位”、“以公里为单位的长度”等),我想使用占位符并在 XAML 代码中设置它们。

我想过这样的事情

资源“UI_Length”的值

Length in {0}

在 CodeBehind 中,使用 String.Format 很容易

String.Format(
        LocalizeDictionary.Instance.GetLocalizedObject("UI_Length", null, LocalizeDictionary.Instance.Culture).ToString(), 
       "Meters");

但是如何在 XAML 中添加另一个字符串甚至另一个资源条目?

<Label x:Name="Label" Content="{lex:LocText Key=UI_Length}, Meters" HorizontalAlignment="Left" VerticalAlignment="Top"/>

根据Binding placeholder from resource file in WPF,这似乎是可能的,但我无法让它运行标签

[更新]

我设法添加了两个资源值。 诀窍是在 Label.Content 中添加一个 TextBlock。 see Link

        <Label  Grid.Row="1">
            <Label.Content>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}{0} [{1}]">
                            <Binding Source="{lex:LocText Key=UI_Length}" />
                            <Binding Source="{lex:LocText Key=UI_MeterShort}" />
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </Label.Content>
        </Label>

但是我这里还是有问题。在启动时这工作正常但是当我尝试切换语言时

LocalizeDictionary.Instance.Culture = new CultureInfo("de-DE");

我收到“绑定使用后无法更改”。错误。 是否有类似的方法可以使用多个 Resource 值并且仍然能够在运行时切换语言?

[更新 2]

我尝试了 Liero 的建议,但这里仍然存在问题。

在我的 MainView 中,我将 DataContext 设置为 MainViewModel。 VM 有一个 LocalizedTexts 实例。在 ViewModel 中更改语言后,我调用 RaisePropertiesChanged() 但没有得到任何输出。

TextBlock 绑定到 LengthInMeters

<TextBlock Text="{Binding LocalizedTexsts.LengthInMeters}" />

我在更改语言后调用 RaisePorpertyChanged:

    public void ChangeLanguage(string culture)
    {
         LocalizeDictionary.Instance.Culture = new CultureInfo(culture);
         _localizedTexts.RaisePropertyChanged();
    }

LengthInMeters 看起来像这样:

public string LengthInMeters
{
    get
    {
        return String.Format(
                   LocalizeDictionary.Instance.GetLocalizedObject(
                       "UI_Length", null,
                       LocalizeDictionary.Instance.Culture).ToString(),
                   LocalizeDictionary.Instance.GetLocalizedObject(
                       "UI_Meters", null,
                       LocalizeDictionary.Instance.Culture).ToString()
               );
    }
}

但 TextBlock 保持为空。

【问题讨论】:

    标签: wpf xaml wpflocalizationextension


    【解决方案1】:

    首先,你可以像这样缩短绑定:

    <TextBlock Text="{Binding Source={lex:LocText Key=UI_MeterShort}, 
                              StringFormat={lex:LocText Key=UI_Length}}" />
    

    其次,如果你想更新绑定,当语言发生变化时,你需要在代码隐藏中找到TextBlock并使用BindingExpression.UpdateTarget()方法手动更新绑定。但这很奇怪,不是吗?

    或者,您可以通过删除所有内容并创建新内容来刷新整个窗口。我的意思是从窗口中删除 UserControl 并创建新的 UserControl。

    但是,这两种解决方案都很奇怪,因为它只是解决了 WPF 中滥用绑定引起的问题。让我建议更好的方法。

    public class LocalizedTexts: INotifyPropertyChanged
    {
       public event PropertyChanged;
    
    
       public LengthInMeters { get { return String.Format(...); } }
    
       public LengthInKilometers {get { return String.Format(...); } }
    
    
       public void RaisePropertiesChanged()
       {
          foreach (var property in this.GetType().GetProperties())
          {
             PropertyChanged(this, new PropertyChangedEventArgs(property.Name))
          }
       }
    }
    

    现在您可以将数据绑定到 LocalizedTexts,当语言发生变化时,只需致电 RaisePropertiesChanged()

    用法:

    <Application.Resources>
        <l:LocalizedTexts x:Key="LocalizedTexts" />
    </Application.Resources>
    
    <TextBlock Text="{Binding LengthInMeters, Source={StaticResource LocalizedTexts}}" />
    
    
    <!-- instead of using StaticResource, you can add l:LocalizedTexts  as a property to your viewmodel -->
    <TextBlock Text="{Binding LocalizedTexts.LengthInMeters}" />
    

    【讨论】:

    • 我尝试了您建议的方法,但这里仍然存在问题。我所做的是:在我的 MainView 中,我将 DataContext 设置为 MainViewModel。 VM 有一个 LocalizedTexts 实例。在 ViewModel 中更改语言后,我调用 RaisePropertiesChanged() 但没有得到任何输出。 => 请查看更新 2 了解更多详情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多