如何编辑resx文件(资源键值)运行时wpf c#

时间:2016-01-26 12:40:07

标签: c# wpf resources resx

我有多种语言的多语言应用程序。在我的应用程序中有用户可以更改的文本,但默认文本也需要翻译成不同的语言。这意味着如果用户想要编辑某些文本,则需要为他的语言编辑resx文件。

首先我尝试使用ResourceWriter类,然后我的resx文件被破坏了。我又创造了。

其次我尝试使用ResXResourceWriter课程,但我找不到能给我这个功能的好方法(编辑某些属性的值)。

我认为只需阅读像xml这样的resx文件并进行编辑,但我不知道如何再次构建应用程序。

是否可以在运行时从应用程序编辑resx中的值。之后就可以使用c#代码构建应用程序,就像在visual studio中构建一样。

编辑我不想将resx文件从 .en.resx更改为其他方面( .de.resx)。我想更改此resx文件中的值。例如,我有一个关键是btnCont值为Click。我想改变btnCont以获得新价值点击我,例如。然后再次生成更改的resx文件的dll。

感谢您的建议

2 个答案:

答案 0 :(得分:0)

也许有更好的方法可以做到这一点(我很想了解它们),但是当我需要在运行时更改语言时,我所做的就是将所有可本地化的字符串作为readonly属性添加到我的viewmodel。

    public string ImportString { get { return lang.Import; } }

然后我只是从XAML添加一个绑定到这个字符串,并在更改UI文化后,我在我的viewmodel的所有字符串属性上调用OnPropertyChanged。

    protected void NotifyAllPropertiesChanged<T>()
    {
        foreach (var p in this.GetType().GetProperties())
            if (p.PropertyType == typeof(T))
                OnPropertyChanged(p.Name);
    }

答案 1 :(得分:0)

尝试编译以下代码

    <Window x:Class="WPFLocalizationSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
    <StackPanel HorizontalAlignment="Left" Margin="20" VerticalAlignment="Top">
        <TextBlock Text="{DynamicResource tbName}" Margin="2" />
        <TextBox Width="200" Margin="2"/>
        <Button Content="{DynamicResource btnAdd}" HorizontalAlignment="Left" Margin="2" />
    </StackPanel>


    <StackPanel HorizontalAlignment="Left" Margin="20,181,0,0" VerticalAlignment="Top" Orientation="Vertical" Width="305">
        <TextBlock Text="Translation Panel" FontSize="20" FontWeight="Black" />
        <Grid >
            <TextBlock Text="{DynamicResource tbName}" Margin="2"  />
            <TextBox Width="200" Margin="2" HorizontalAlignment="Right" Tag="tbName"   x:Name="tbNameLoc"/>
        </Grid>
        <Grid>
            <TextBlock Text="{DynamicResource btnAdd}" Margin="2" />
            <TextBox Width="200" Margin="2" HorizontalAlignment="Right" Tag="btnAdd" x:Name="btnAddLoc" />
        </Grid>
        <Button Content="Translate/Update" HorizontalAlignment="Left" Margin="2" Click="Button_Click" />
    </StackPanel>
    </Grid>
  </Window>

这是MainWindow.Xaml.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;

namespace WPFLocalizationSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    private static ResourceDictionary CurrentLanguageDictionary;
    private static string LanguageResourceFile = "en-US.xaml";
    private Dictionary<string, System.Windows.Controls.TextBox> TextBoxControls = new Dictionary<string, TextBox>();
    public MainWindow()
    {
        InitializeComponent();
        AddControlsToLocalization();
    }

    private void AddControlsToLocalization()
    {
        TextBoxControls.Add("tbName", tbNameLoc);
        TextBoxControls.Add("btnAdd", btnAddLoc);
    }

    public static bool SaveLanguageFile(Dictionary<string, System.Windows.Controls.TextBox> TextBoxControls, string selectedLang)
    {

        bool status = false;
        try
        {
            using (var fs = new FileStream(LanguageResourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // Read in ResourceDictionary File
                CurrentLanguageDictionary = (ResourceDictionary)XamlReader.Load(fs);
            }

            foreach (string key in TextBoxControls.Keys)
            {
                TextBox txt = TextBoxControls[key];
                if (txt.Text.Length > 0)
                {
                    CurrentLanguageDictionary[key] = txt.Text;
                }
            }

            using (var writer = new StreamWriter(LanguageResourceFile))
            {
                XamlWriter.Save(CurrentLanguageDictionary, writer);
            }
            status = true;
        }
        catch (Exception _exception)
        {
            MessageBox.Show("Exception in language file edit");
            return false;
        }

        SetLanguageResourceDictionary(LanguageResourceFile, App.Current);

        return status;

    }
    public static void SetLanguageResourceDictionary(String inFile, Application application)
    {
        if (File.Exists(inFile))
        {
            // Read in ResourceDictionary File
            var languageDictionary = new ResourceDictionary();
            languageDictionary.Source = new Uri(inFile,UriKind.Relative);

            // Remove any previous Localization dictionaries loaded
            int langDictId = -1;
            for (int i = 0; i < application.Resources.MergedDictionaries.Count; i++)
            {
                var md = application.Resources.MergedDictionaries[i];
                // Make sure your Localization ResourceDictionarys have the ResourceDictionaryName
                // key and that it is set to a value starting with "Loc-".
                if (md.Contains("ResourceDictionaryName"))
                {
                    if (md["ResourceDictionaryName"].ToString().Equals("en-US"))
                    {
                        langDictId = i;
                        break;
                    }
                }
            }
            if (langDictId == -1)
            {
                // Add in newly loaded Resource Dictionary
                application.Resources.MergedDictionaries.Add(languageDictionary);
            }
            else
            {
                // Replace the current langage dictionary with the new one
                application.Resources.MergedDictionaries[langDictId] = languageDictionary;
            }
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        SaveLanguageFile(TextBoxControls, "en-US");
    }
}
}

以下是en-US.xaml示例(资源字典文件)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:sys="clr-namespace:System;assembly=mscorlib"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<sys:String x:Key="ResourceDictionaryName">en-US</sys:String>
<sys:String x:Key="tbName">Enter youe Name</sys:String>
<sys:String x:Key="btnAdd">Add</sys:String>

</ResourceDictionary>

在app.xaml中添加资源文件

<Application x:Class="WPFLocalizationSample.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="en-US.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
</Application>

如果你编译它,你会看到一个带有两个样本控件的表单。 下面翻译面板补充说。您可以键入要更改的任何文本 点击翻译按钮更改的文本将在en-US文件中更新。 如果你想保存不同的文件也可以。

注意:en-US.xaml文件应该在release文件夹中。