gpt4 book ai didi

c# - 在 WinForms 中以可本地化的形式在运行时更改 CurrentUICulture

转载 作者:太空宇宙 更新时间:2023-11-03 22:54:35 24 4
gpt4 key购买 nike

我一直在搜索如何更改具有 Localizable 的表单的语言属性设置为 true。

https://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture(v=vs.110).aspx

这个是设置窗体的语言,但是这个需要在我们实例化窗体之前设置。在此事件之后无法调用。

搜索资料,我看到了以下问题:https://stackoverflow.com/a/11738932/3286975但是,正如评论所说,我在 TabControl 和 MenuStrip 中有控件,因此它们不受影响。

我试图通过获取表单的所有控件来修改它,但没有运气。

enter image description here

enter image description here

在此菜单中,我调用了以下回调:

    private void englishToolStripMenuItem_Click_1(object sender, EventArgs e)
{
string lang = (string) ((ToolStripMenuItem) sender).Tag;
base.Culture = CultureInfo.CreateSpecificCulture(lang);
}

private void spanishToolStripMenuItem_Click(object sender, EventArgs e)
{
string lang = (string) ((ToolStripMenuItem) sender).Tag;
base.Culture = CultureInfo.CreateSpecificCulture(lang);
}

我通过使用标签来改变文化。

当我点击它时没有任何反应。此外,我对上述答案中的 ApplyResources 方法进行了一些修改。

private void ApplyResources(Control parent, CultureInfo culture)
{
this.resManager.ApplyResources(parent, parent.Name, culture);

foreach (Control ctl in parent.IterateAllChildren())
{
//this.ApplyResources(ctl, culture);
this.resManager.ApplyResources(ctl, ctl.Name, culture);
}
}

其中 IterateAllChildren 如下:https://stackoverflow.com/a/16725020/3286975

此外,我尝试使用 (System.LINQ):Controls.OfType<Label>() (因为我有一个标签来测试这个)运气不好......

enter image description here

enter image description here

但是当我选择西类牙语时,没有任何文本发生变化。

所以也许,我对 children 感到失望。或者可能通过调用方法 CreateCulture ,我不知道。

提前致谢!

编辑:

我已经测试过通过 Culture Info 获取我的表单的资源管理器,它每次都返回默认值:

 ResourceSet resourceSet = new ResourceManager(typeof(frmCredentials)).GetResourceSet(new CultureInfo(lang), true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value; //resourceSet.GetString(resourceKey);
if (resource.GetType().Equals(typeof(string)))
Console.WriteLine("Key: {0}\nValue: {1}\n\n", resourceKey, (string) resource);
}

在哪里new CultureInfo(lang) ,我也测试过:new CultureInfo("es") & Thread.CurrentThread.CurrentCulture (CurrentUICulture) 没有运气。就像它从不存在或被替换,但在我的设计和文件资源管理器中我可以看到这些文件。

编辑 2:

可能是因为我正在使用 ILMerge 将所有 dll 合并到一个唯一的 dll 中。我正在审查这个:Single-assembly multi-language Windows Forms deployment (ILMerge and satellite assemblies / localization) - possible?

回复EDIT2:

是的,删除ILMerge问题解决了,我给出的第一个解决方案解决了这个问题。但由于某种原因,西类牙语被用作默认语言,当我尝试从中获取资源集时,它没有返回任何内容。

此外,我已将 Localizable 属性设置为 false,并且它没有创建带有值的默认 resx 文件。我不知道这是否是一个好习惯。

我会尝试一些新的东西...

最佳答案

MVVM(模型 - View - ViewModel)方法有一些好处,对您的情况很有用。

为您将用于本地化的语言创建新的资源文件。使用表单自己的资源文件可能有点棘手,因为每次您在设计器中进行更改时它都会重新生成 - 所以我认为自己的资源文件将更容易维护,甚至与其他表单甚至项目共享。

LocalizationValues.resx // (default english), set Access Modifier to "Internal" or "Public"
"Title": "Title"
"Description": "Description"

LocalizationValues.es.resx
"Title": "Título"
"Description": "Descripción"

Visual Studio 生成静态类 LocalizationValues,并将属性作为 .resx 文件的键。所以“Title”可以作为 LocalizationValues.Title

访问

创建代表您在本地化中使用的所有文本的“viewmodel”类。类应实现 INotifyPropertyChanged 接口(interface)。

public class LocalizationViewModel : INotifyPropertyChanged
{
public string Title
{
get
{
return LocalizationValues.Title;
}
}

public string Description
{
get
{
return LocalizationValues.Description;
}
}

public void SetLanguage(string language)
{
var culture = new CultureInfo(language);
Thread.CurrentThread.CurrentUICulture = culture;

// This is important,
// By raising PropertyChanged you notify Form to update bounded controls
NotifyAllPropertyChanged();
}

public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyAllPropertyChanged()
{
// Passing empty string as propertyName
// will indicate that all properties of viewmodel have changed
NotifyPropertyChanged(string.Empty);
}

protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

然后在Form中将viewmodel绑定(bind)到控件上

public partial class YourForm : Form
{
private LocalizationViewModel _viewmodel;

public YourForm()
{
InitializeComponent();

_viewmodel = new LocalizationViewModel();

// Bound controls to correspondent viewmodel's properties
LblTitle.DataBindings.Add("Text", _viewmodel, "Title", true);
LblDescription.DataBindings.Add("Text", _viewmodel, "Description", true);
}

// Menu buttons to change language
private void SpanishToolStripMenuItem_Click(object sender, EventArgs e)
{
_viewmodel.SetLanguage("es");
}

private void EnglishToolStripMenuItem_Click(object sender, EventArgs e)
{
_viewmodel.SetLanguage("en");
}
}

上述方法将提供比仅更新控件更多的好处。您可以清楚地分离应用程序的各个部分,这些部分可以相互独立地进行测试。

关于c# - 在 WinForms 中以可本地化的形式在运行时更改 CurrentUICulture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46007638/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com