C# - Windows窗体本地化(语言)在运行时更改 - ListView列标题不会更改语言

时间:2013-02-11 16:46:29

标签: c# listview localization runtime

我目前正在开发一个必须支持6种不同语言的项目。我已经有一个工作实现使用资源文件进行字符串和表单本地化控件。实现的最后部分涉及在程序运行时实时更改语言。我已经看到了如何做到这一点的建议,最后我使用了ApplyResources方法的修改版本。总的来说,我在谈论这种事情:

ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
CultureInfo culture = new CultureInfo("fr-FR");

resources.ApplyResources(_mybutton, _mybutton.Name, culture);

因此,按钮“_mybutton”文本将更改为法语本地化版本。这适用于我的所有表单和控件,特殊于ListView控件的EXCEPT。此ListView有5列对象类型ColumnHeader。我正在尝试使用ApplyResources将列标题的文本更改为新语言。我已经在.fr.resx资源文件中为列标题添加了相应的法语文本,当我将表单本地化切换为法语时,Designer视图向我显示法语翻译版本,正如预期的那样。

更进一步,我尝试在构造函数中的表单的InitializeComponent()方法之前将全局线程currentUICulture属性更改为French。我确认这将为列表视图中的列标题加载正确的法语资源。

但是,当我尝试将文化手动应用于ColumnHeader / ListView资源时,我的问题就出现了。例如,我会说代码看起来大致如下:

ComponentResourceManager resources = new ComponentResourceManager(typeof(myUserControl));
CultureInfo culture = new CultureInfo("fr-FR"); 
resources.ApplyResources(_myListView, _myListView.Name, culture);
resources.ApplyResources(_myColumnHeader1, _myColumnHeader1.Name, culture);
this.Refresh();

无论我尝试什么,我都无法将法语资源应用于列标题文本。我也尝试过:

 resources.ApplyResources(_myListView.Columns[0], _myListView.Columns[0].Name, culture);

我在stackoverflow上搜索解决方案之后尝试了类似的东西:

 var lv = (ListView)_myListView;
 foreach (ColumnHeader col in lv.Columns)
 {
     resources.ApplyResources(col, col.Name, culture);
 }

同样的效果 - 没有语言变化。我查看了Designer.cs代码,看看是否存在任何重要的差异或缺少的行,看起来我正在做的正确。所有其他控件都正确地更改了语言,但listview中的列标题拒绝动态更改文本。谁看过这个吗?我在这做错了什么?

在最糟糕的情况下,我可以将列标题的文本移动到外部资源文件,然后手动设置每个列标题的文本,但我发现这是一个很大的麻烦,特别是如果我必须稍后处理具有许多列的列表视图,或者如果文本需要为每种语言具有多个值。非常感谢帮助!

2 个答案:

答案 0 :(得分:3)

我对自己的问题进行了更多研究,看来.NET Framework中实际上存在一个错误,即ColumnHeader对象的.Name方法实际上并没有正确地返回对象名称。这就是我尝试将资源应用于对象失败的原因。

我能够通过对ColumnHeaders的更改进行硬编码来解决问题。例如:

resources.ApplyResources(_myHeader, "_myHeader", culture);

你基本上只是用名称的文字字符串替换.Name的调用。我测试了这个并且它有效。不幸的是,这意味着它不适合我用来更改所有控件的代码的一部分。我必须为每个需要更改的ColumnHeader对象添加一行。幸运的是,我没有使用具有可变数量列的列表视图,因为这可能会变得棘手。

另一种选择是创建本地化资源文件。您可能已经将它们用于消息框文本和其他字符串之类的内容。然后,您可以在资源文件中添加一个条目,如“columnHeader_myHeader”,并为每种语言设置相应的语言文本。最后,您可以使用以下方法手动将文本更改为列标题:

_myHeader.Text = myResourceFileName.columnHeader_myHeader;

这将根据当前的线程文化选择合适的语言。

答案 1 :(得分:0)

似乎列标题的名称属性仍然没有显示列标题的名称。像这样,遍历所有列均无效:

foreach (ColumnHeader col in lv.Columns)
{
     resources.ApplyResources(col, col.Name, culture);
}