代码之家  ›  专栏  ›  技术社区  ›  BarryLib

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

  •  2
  • BarryLib  · 技术社区  · 7 年前

    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文件,但我还想在代码背后更改viewmodel的语言。

    xaml中的My 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();
            }
        }
    }
    

        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",
                    }
                };
        }
    

    Code Name , Description

    1 回复  |  直到 5 年前
        1
  •  3
  •   Kohei TAMURA    7 年前

    我将为您提出一个在运行时更改语言的解决方案。

    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. 根据需要为每种语言类型定义资源文件。 enter image description here 在上面,我为英语定义了默认值,为德语定义了第二个文件(您可以看到扩展名“.de”。对于任何其他语言也是如此。 确保打开了资源。resx属性并选择值作为自定义工具 PublicResXFileCodeGenerator enter image description here

    3. 通过App.xaml中的对象提供程序注册资源提供程序: enter image description here

    4. 用法:

      Text=“{Binding ResourcesText1,Source={StaticResource Resources}}”

    来自*。反恐精英: Resources.ResourcesText1

    附笔。 当你改变文化时,一定要打电话 集合培养 方法 文化资源