gpt4 book ai didi

wpf - 在 XAML 中为 WPF 本地化扩展使用占位符

转载 作者:行者123 更新时间:2023-12-04 18:48:11 24 4
gpt4 key购买 nike

我在我的程序中使用 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");

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

[更新 2]

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

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

TextBlock 绑定(bind)到 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 保持为空。

最佳答案

首先,您可以像这样缩短绑定(bind):

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

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

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

但是,这两种解决方案都很奇怪,因为它只是解决了因滥用 WPF 中的绑定(bind)而导致的问题。让我提出更好的方法。

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))
}
}
}

现在您可以将数据绑定(bind)到 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}" />

关于wpf - 在 XAML 中为 WPF 本地化扩展使用占位符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39123448/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com