我应该改变啥来使用 wpf 准备多语言 wpf 应用程序

Posted

技术标签:

【中文标题】我应该改变啥来使用 wpf 准备多语言 wpf 应用程序【英文标题】:What should I change to prepare multilingual wpf application with wpf我应该改变什么来使用 wpf 准备多语言 wpf 应用程序 【发布时间】:2019-12-09 16:31:51 【问题描述】:

我想用多语言用户界面编写 WPF MVVM 应用程序。 (在同一屏幕上)我有一个“更改语言”按钮。我想当我点击按钮时用户界面语言会改变 我想通过 button.s 使用从土耳其语翻译 UI 英语和从英语翻译土耳其语 我准备了所有 resx 文件,并分享了我的所有代码。 我的代码工作正常。(但是当我点击按钮时语言没有改变 UI 语言不变

我正在分享我所有的代码,请帮助我。

//MainWindow.xaml It's my xaml class I use bindings and resources.

<Window x:Class = "WPFLocalization.MainWindow" 
       xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local = "clr-namespace:WPFLocalization" 
       xmlns:p = "clr-namespace:WPFLocalization.Properties"
       Title = "x:Static p:Resources.Title" Height = "350" Width = "604">

        <Grid>
            <TextBox x:Name = "textBox" HorizontalAlignment = "Left" Height = "23" 
             Margin = "128,45,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/>
            <Label x:Name = "label" Content = "x:Static p:Resources.Name"
             HorizontalAlignment = "Left" Margin = "52,45,0,0" VerticalAlignment = "Top" Width = "86"/>

            <TextBox x:Name = "textBox1" HorizontalAlignment = "Left" Height = "23" 
             Margin = "128,102,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "304"/>

            <Label x:Name = "label1" Content = "x:Static p:Resources.Address" 
             HorizontalAlignment = "Left" Margin = "52,102,0,0" VerticalAlignment = "Top" Width = "86"/>

            <TextBox x:Name = "textBox2" HorizontalAlignment = "Left" Height = "23" 
             Margin = "128,157,0,0" TextWrapping = "Wrap" VerticalAlignment = "Top" Width = "80"/>

            <Label x:Name = "label2" Content = "x:Static p:Resources.Age" 
             HorizontalAlignment = "Left" Margin = "52,157,0,0" VerticalAlignment = "Top" Width = "86"/>

            <Button x:Name = "button" Content = "x:Static p:Resources.OK_Button" 
             HorizontalAlignment = "Left" Margin = "128,241,0,0" VerticalAlignment = "Top" Width = "80"/>

            <Button x:Name = "button1" Content = "x:Static p:Resources.Cancel_Button" 
             HorizontalAlignment = "Left" Margin = "265,241,0,0" VerticalAlignment = "Top" Width = "80">

            </Button>

            <Button x:Name = "button2" Content = "x:Static p:Resources.Help_Button" 
             HorizontalAlignment = "Left" Margin = "380,241,0,0" VerticalAlignment = "Top" Width = "70"/>
            <Button x:Name="button3" Command= "Binding ChangeButtonCommand"  Content= "x:Static p:Resources.Change_Button" 
            HorizontalAlignment="Left" Margin="470,241,0,0" VerticalAlignment="Top" Width="100"/>
        </Grid> 

    </Window>
//LocalizationViewModel.cs It 's my MVVM class.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Configuration;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    namespace WPFLocalization
    
 class LocalizationViewModel : ViewModelBase
        
           public LocalizationViewModel()//Constructor
            

            
            #region Commands

            #region changeButtonCommand
            private DelegateCommand _changeButtonCommand;
            public DelegateCommand ChangeButtonCommand
            
                get
                
                    return _changeButtonCommand ?? (_changeButtonCommand = new DelegateCommand(ExecuteLocalization, CanExecuteLocalization));

                
            



            public bool CanExecuteLocalization()
            



                return true;
            


            public void ExecuteLocalization()
            

                Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US");
                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");




            
        

        #endregion
        #endregion
    





   // DelegateCommand.cs// its constant.
 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Input;

    namespace WPFLocalization
    
        //https://www.codecompiled.com/wpf/implementing-icommand-in-wpf-using-mvvm/
        public class DelegateCommand : ICommand
        
            public event EventHandler CanExecuteChanged
            
                add  CommandManager.RequerySuggested += value; 
                remove  CommandManager.RequerySuggested -= value; 
            

            private readonly Action _executeMethod;
            private readonly Func<bool> _canExecuteMethod;

            public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod)
            
                _executeMethod = executeMethod;
                _canExecuteMethod = canExecuteMethod;
            
            //public void RaiseCanExecuteChanged()
            //
            //    if (CanExecuteChanged != null)
            //        CanExecuteChanged(this, new EventArgs());
            //

            public bool CanExecute()
            
                if (_canExecuteMethod != null)
                
                    return _canExecuteMethod();
                
                return true;
            

            public void Execute()
            
                if (_executeMethod != null)
                
                    _executeMethod();
                
            
            bool ICommand.CanExecute(object parameter)
            
                return CanExecute();
            

            void ICommand.Execute(object parameter)
            
                Execute();
            
        

        public class DelegateCommand<T> : ICommand
        
            public event EventHandler CanExecuteChanged
            
                add  CommandManager.RequerySuggested += value; 
                remove  CommandManager.RequerySuggested -= value; 
            
            private readonly Action<T> _executeMethod;
            private readonly Func<T, bool> _canExecuteMethod;

            #region Constructors
            public DelegateCommand(Action<T> executeMethod)
            
                _executeMethod = executeMethod;
            
            public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
            
                _executeMethod = executeMethod;
                _canExecuteMethod = canExecuteMethod;
            
            #endregion

            #region Public Methods
            public bool CanExecute(T parameter)
            
                if (_canExecuteMethod != null)
                
                    return _canExecuteMethod(parameter);
                
                return true;
            

            public void Execute(T parameter)
            
                if (_executeMethod != null)
                
                    _executeMethod(parameter);
                
            
            #endregion

            #region ICommand Members

            bool ICommand.CanExecute(object parameter)
            
                if (parameter == null &&
                    typeof(T).IsValueType)
                
                    return _canExecuteMethod == null;
                
                return CanExecute((T)parameter);
            

            void ICommand.Execute(object parameter)
            
                Execute((T)parameter);
            

            #endregion
        
    

我不接受错误信息。只有 UI 不会改变。 请帮帮我

【问题讨论】:

WPF: How to change the CurrentUICulture at runtime的可能重复 它不使用 mvvm 接受的重复回答解释了为什么“语言没有改变”。您必须重新加载资源(例如,通过再次关闭和打开窗口)。 【参考方案1】:

我认为您需要在更新语言后刷新屏幕。也许看看这个项目可能会让你朝着正确的方向前进。

https://jeremybytes.blogspot.com/2013/07/changing-culture-in-wpf.html

从外观上看,整个窗口需要在文化改变后重新创建。创建 Jeremy 在 App.xaml.cs 中提到的静态函数,并使用您的新文化从 ExecuteLocalization() 调用它。

【讨论】:

我不明白我该怎么做对不起。 我已经用更好的解释更新了答案。 嗨,我可以在没有新窗口的情况下做同样的事情吗? 另一种选择是让您的标签成为视图模型上返回字符串资源的属性,当您执行语言更改时,为这些属性调用 PropertyChanged 以刷新绑定。 我是 WPF 的新手。我不知道该怎么做?如果可能的话,你能举个例子。我想学习。

以上是关于我应该改变啥来使用 wpf 准备多语言 wpf 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

多语言 wpf 应用程序

WPF中的多语言[关闭]

WPF 实现多语言支持

WPF使用X:Static做多语言支持

WPF使用X:Static做多语言支持

DotNetCore 3.0 助力 WPF本地化