You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在代码中创建类似{lex:LocTextUpper XXX}的本地化绑定?

解决方案:代码创建控件时保留本地化自动更新能力

其实这个需求在WPF里完全可以实现,核心就是利用资源文件(.resx)结合数据绑定,哪怕是纯代码创建的控件,也能像XAML里那样自动响应区域性变更。下面分步骤给你说怎么做:

1. 准备本地化资源文件

首先你得有标准的.resx资源文件,比如Strings.resx(默认语言),然后创建对应区域性的文件比如Strings.zh-CN.resx、Strings.en-US.resx,里面存好要本地化的字符串键值对,比如Greeting对应"你好"和"Hello"。

2. 用代码绑定资源到控件

在代码里创建控件时,不要直接给Content或Text赋值静态字符串,而是用Binding绑定到资源文件的属性,同时要确保绑定能监听区域性变化。这里有两种常用方式:

方式一:封装可通知的本地化管理类

默认的.resx生成的类是静态的,没法通知属性变化,所以我们可以自己封装一个单例类,实现INotifyPropertyChanged,当区域性变更时触发属性更新:

public class LocalizationManager : INotifyPropertyChanged
{
    public static LocalizationManager Instance { get; } = new LocalizationManager();

    public string Greeting => Strings.Greeting;
    public string ConfirmText => Strings.Confirm;
    // 其他需要本地化的属性...

    public event PropertyChangedEventHandler? PropertyChanged;

    // 当区域性变更时调用这个方法,通知所有绑定控件更新
    public void OnCultureChanged()
    {
        // 可以逐个触发属性变更,或者用string.Empty触发所有属性更新
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty));
    }
}

然后在代码创建控件时绑定:

var greetingLabel = new Label();
greetingLabel.SetBinding(ContentProperty, new Binding(nameof(LocalizationManager.Greeting))
{
    Source = LocalizationManager.Instance,
    Mode = BindingMode.OneWay
});

var confirmBtn = new Button();
confirmBtn.SetBinding(ContentProperty, new Binding(nameof(LocalizationManager.ConfirmText))
{
    Source = LocalizationManager.Instance,
    Mode = BindingMode.OneWay
});

当你切换区域性(比如Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");),只要调用LocalizationManager.Instance.OnCultureChanged();,所有绑定的控件就会自动更新文本了。

方式二:使用DynamicResource绑定资源字典

另一种方式是把本地化字符串放到资源字典里,然后用DynamicResource绑定,这样当区域性变更时替换资源字典,控件会自动更新。

首先,在App.xaml或者专门的资源文件里定义不同区域性的资源字典:

<!-- 中文资源字典 -->
<ResourceDictionary x:Key="ZhCnResources">
    <system:String x:Key="Greeting">你好</system:String>
    <system:String x:Key="Confirm">确认</system:String>
</ResourceDictionary>

<!-- 英文资源字典 -->
<ResourceDictionary x:Key="EnUsResources">
    <system:String x:Key="Greeting">Hello</system:String>
    <system:String x:Key="Confirm">Confirm</system:String>
</ResourceDictionary>

然后在代码里创建控件时用DynamicResource:

var greetingLabel = new Label();
greetingLabel.SetResourceReference(ContentProperty, "Greeting");

var confirmBtn = new Button();
confirmBtn.SetResourceReference(ContentProperty, "Confirm");

当切换区域性时,替换当前的资源字典:

private void SwitchToEnglish()
{
    Application.Current.Resources.MergedDictionaries.Clear();
    if (Application.Current.Resources["EnUsResources"] is ResourceDictionary enDict)
    {
        Application.Current.Resources.MergedDictionaries.Add(enDict);
    }
}

这种方式不需要手动触发属性变更,WPF会自动检测资源字典的变化并更新控件。

3. 额外技巧:自动监听区域性变更

如果你想更省心,可以在App启动时监听区域性变更事件,自动触发更新。比如在App.xaml.cs里:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    // 监听系统区域性变更
    CultureInfo.CurrentCultureChanged += (s, args) =>
    {
        LocalizationManager.Instance.OnCultureChanged();
        // 或者替换资源字典的逻辑,根据你的方式选择
    };
}

这样只要系统的区域性变了,你的控件文本就会自动更新,完全不用手动处理。


内容的提问来源于stack exchange,提问作者Gábor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:39:37