如何在运行时使用资源字典更改 UI 语言?

2024-03-18

我想通过button_click事件更改我的项目语言,所以我使用ResourceDictionary来执行以下操作:

XAML

    <Button Content="{DynamicResource LanguageSetting}" Click="btn_LanguageSetting_Click"/>

代码隐藏

    public static string windowCurrentLanguageFile = "Language/en.xaml";
    private void btn_LanguageSetting_Click(object sender, RoutedEventArgs e)
    {
        windowCurrentLanguageFile = windowCurrentLanguageFile == "Language/en.xaml"
            ? "Language/fr.xaml"
            : "Language/en.xaml";

        var rd = new ResourceDictionary() { Source = new Uri(windowCurrentLanguageFile, UriKind.RelativeOrAbsolute) };

        if (this.Resources.MergedDictionaries.Count == 0)
            this.Resources.MergedDictionaries.Add(rd);
        else
            this.Resources.MergedDictionaries[0] = rd;
    }

这对于 xaml 文件效果很好,但我也想在后面的代码中更改视图模型的语言。

xaml 中的我的 ItemsControl:

<ItemsControl ItemsSource="{Binding ItemOperate}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewmodel:SelectableViewModel}">
                <Border x:Name="Border" Padding="0,8,0,8" BorderThickness="0 0 0 1" BorderBrush="{DynamicResource MaterialDesignDivider}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Checkerz" />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <ToggleButton VerticalAlignment="Center" IsChecked="{Binding IsSelected}"
                                      Style="{StaticResource MaterialDesignActionLightToggleButton}"
                                      Content="{Binding Code}" />
                        <StackPanel Margin="8 0 0 0" Grid.Column="7">
                            <TextBlock FontWeight="Bold" Text="{Binding Name}" />
                            <TextBlock Text="{Binding Description}" />
                        </StackPanel>
                    </Grid>
                </Border>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsSelected}" Value="True">
                        <Setter TargetName="Border" Property="Background" Value="{DynamicResource MaterialDesignSelection}" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

哪个绑定到视图模型像这样:

public class SelectableViewModel : INotifyPropertyChanged
{ 
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            if (_isSelected == value) return;
            _isSelected = value;
            OnPropertyChanged();
        }
    }

    private char _code;
    public char Code
    {
        get { return _code; }
        set
        {
            if (_code == value) return;
            _code = value;
            OnPropertyChanged();
        }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;
            _name = value;
            OnPropertyChanged();
        }
    }

    private string _description;
    public string Description
    {
        get { return _description; }
        set
        {
            if (_description == value) return;
            _description = value;
            OnPropertyChanged();
        }
    }
}

And

    public MainViewModel()
    {
        _itemOperate = CreateData();
    }

    private static ObservableCollection<SelectableViewModel> CreateData()
    {
        return new ObservableCollection<SelectableViewModel>
            {
                new SelectableViewModel
                {
                    Code = 'E', 
                    Name = "Erase",
                    Description = "Erase The MCU Chip By Page"
                },
                new SelectableViewModel
                {
                    Code = 'D',
                    Name = "Detect",
                    Description = "Detect The MCU Flash",
                },
                new SelectableViewModel
                {
                    Code = 'P',
                    Name = "Programming",
                    Description = "Programming The MCU Chip By Hex File",
                },
                new SelectableViewModel
                {
                    Code = 'V',
                    Name = "Verify",
                    Description = "Verify The Downing Code",
                },
                new SelectableViewModel
                {
                    Code ='L',
                    Name = "Lock",
                    Description = "Lock The Code To Protect The MCU",
                }
            };
    }

那么我应该如何更改我的模型 SelectableViewModel 的语言Code, Name, Description而不是使用这个硬代码?谢谢!


我将向您建议一个在运行时更改语言的解决方案。

  1. 创建资源管理器:

    public class CultureResources
    {
        private static bool isAvailableCulture;
        private static readonly List<CultureInfo> SupportedCultures = new List<CultureInfo>();
        private static ObjectDataProvider provider;
    
        public CultureResources()
        {
            GetAvailableCultures();
        }
    
            /// <summary>
            /// Gets automatically all supported cultures resource files.
            /// </summary>
            public void GetAvailableCultures()
            {
    
                if (!isAvailableCulture)
                {
                    var appStartupPath = AppDomain.CurrentDomain.BaseDirectory;
    
                    foreach (string dir in Directory.GetDirectories(appStartupPath))
                    {
                        try
                        {
                            DirectoryInfo dirinfo = new DirectoryInfo(dir);
                            var culture = CultureInfo.GetCultureInfo(dirinfo.Name);
                            SupportedCultures.Add(culture);
                        }
                        catch (ArgumentException)
                        {
                        }
                    }
                    isAvailableCulture = true;
                }
            }
    
            /// <summary>
            /// Retrieves the current resources based on the current culture info
            /// </summary>
            /// <returns></returns>
            public Resources GetResourceInstance()
            {
                return new Resources();
            }
    
            /// <summary>
            /// Gets the ObjectDataProvider wrapped with the current culture resource, to update all localized UIElements by calling ObjectDataProvider.Refresh()
            /// </summary>
            public static ObjectDataProvider ResourceProvider
            {
                get {
                    return provider ??
                           (provider = (ObjectDataProvider)System.Windows.Application.Current.FindResource("Resources"));
                }
            }
    
            /// <summary>
            /// Changes the culture
            /// </summary>
            /// <param name="culture"></param>
            public  void ChangeCulture(CultureInfo culture)
            {
                if (SupportedCultures.Contains(culture))
                {
                    Resources.Culture = culture;
                    ResourceProvider.Refresh();
                }
                else
                {
                    var ci = new CultureInfo("en");
    
                    Resources.Culture = ci;
                    ResourceProvider.Refresh();
                }
            }
    
            /// <summary>
            /// Sets english as default language
            /// </summary>
            public void SetDefaultCulture()
            {
                CultureInfo ci = new CultureInfo("en");
    
                Resources.Culture = ci;
                ResourceProvider.Refresh();
            }
    
            /// <summary>
            /// Returns localized resource specified by the key
            /// </summary>
            /// <param name="key">The key in the resources</param>
            /// <returns></returns>
            public static string GetValue(string key)
            {
                if (key == null) throw new ArgumentNullException();
                return Resources.ResourceManager.GetString(key, Resources.Culture);
            }
    
            /// <summary>
            /// Sets the new culture
            /// </summary>
            /// <param name="cultureInfo">  new CultureInfo("de-DE");  new CultureInfo("en-gb");</param>
            public void SetCulture(CultureInfo cultureInfo)
            {
    
                //get language short format - {de} {en} 
                var ci = new CultureInfo(cultureInfo.Name.Substring(0,2));
                ChangeCulture(ci);
                Thread.CurrentThread.CurrentCulture = cultureInfo;
                Thread.CurrentThread.CurrentUICulture = cultureInfo;
               // CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-GB");
    
            }
        }
    
  2. Define resource file for each language type as you want. enter image description here above I've defined the default for English and the second file for German (you can see the ".de" extension. So you do for any other language. Be sure that you open the Resources.resx properties and select as Custom Tool the value PublicResXFileCodeGenerator. This step is necessary in order to expose the Resource through an object provider. enter image description here

  3. Register the Resource provider via an object provider in the App.xaml: enter image description here

  4. 用法: 在 Xaml 中:

    Text="{绑定资源Text1,源={静态资源资源}}"

来自 *.cs :资源.ResourcesText1.

附: 当你改变文化时,一定要打电话集文化方法从文化资源.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在运行时使用资源字典更改 UI 语言? 的相关文章

  • 需要帮助处理 Application.xaml 文件中的 DataTemplate 事件

    我的应用程序中有一个包含几个按钮的数据模板 我希望这些按钮的偶数处理程序在当前页面 我在许多页面中使用此模板 而不是在 Application xaml vb cs 文件中触发 因为我希望在每个页面上执行不同的操作 我希望我说清楚了 您可以
  • 如何使用 Entity Framework 和 Identity 解决对象处置异常 ASP.NET Core

    我正在尝试编写一个控制器 该控制器接收来自 AJAX 调用的请求并通过 DBContext 对数据库执行一些调用 但是 当我发出命令时var user await GetCurrentUserAsynch 在对 DBContext 的任何调
  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • 在 WCF 上重用我的 PagedList 对象

    问题 我有一个自定义集合PagedList
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 检查两个函数或成员函数指针的签名是否相等

    我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等 它比较提取的返回类型和函数参数 include
  • 列表到优先队列

    我有一个 C 大学编程项目 分为两个部分 在开始第二部分时应该使用priority queues hash tables and BST s 我 至少 在优先级队列方面遇到了麻烦 因为它迫使我自己重做第一部分中已经实现的许多代码 该项目是关
  • ASP.net WebForms - 在标记中使用 GetRouteUrl

    我一直在尝试弄清楚如何将路由功能与 ASP net 4 0 WebForms 一起使用 我将一条路线添加到我的路线集合中 void Application Start RegisterRoutes RouteTable Routes voi
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 意外的 const 引用行为

    include
  • 如何在控制台程序中获取鼠标位置?

    如何在 Windows 控制台程序中用 C 获取鼠标单击位置 点击时返回鼠标位置的变量 我想用简单的文本命令绘制一个菜单 这样当有人点击时 游戏就会注册它并知道位置 我知道如何做我需要做的一切 除了单击时获取鼠标位置 您需要使用 Conso
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 使用任务的经典永无止境的线程循环?

    给出了一个非常常见的线程场景 宣言 private Thread thread private bool isRunning false Start thread new Thread gt NeverEndingProc thread S
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir
  • Asp.Net Core 中的 SSL 不起作用

    我从 Visual Studio 创建了一个简单的 Web 应用程序Web Application Net Core 具有个人用户帐户授权的模板 然后 我启用了 SSLProject gt MyProject Properties 将带有

随机推荐