【问题标题】:How to set text to a control from resource file in design time?如何在设计时将文本从资源文件设置为控件?
【发布时间】:2015-11-27 00:20:45
【问题描述】:

我想知道是否有办法在设计时从资源文件中设置控件的Text 属性:

或者这个过程只能以编程方式执行?

【问题讨论】:

  • 您想使用自己制作的.Resx 文件设置文本属性还是您的实际要求是本地化?
  • 第一个,@RezaAghaei。
  • 我知道以编程方式执行此操作,但我不知道如何在设计时设置控件的 Text 属性。
  • 设计器仅序列化该属性的字符串。您不能直接使用设计器将Text 属性设置为资源值,但您可以以某种方式使用扩展器在设计时为控件设置资源键,然后在运行时使用它。但总的来说,我认为使用 Windows 窗体的标准本地化机制是一个更好的选择。

标签: c# .net winforms localization windows-forms-designer


【解决方案1】:

设计器仅序列化 Text 属性的字符串。您不能直接使用设计器将 Text 属性设置为资源值。

即使您打开Form1.Designer.cs 文件并在初始化中添加一行以将Text 属性设置为Resource1.Key1 之类的资源值,在设计器中首次更改后,设计器也会通过设置字符串值来替换您的代码Text 属性的资源。

一般来说,我建议使用标准的localization windows 窗体机制,使用FormLocalizableLanguage 属性。

但是,如果出于某种原因您想使用资源文件并希望使用基于设计器的解决方案,您可以创建一个 extender component 以在设计时为您的控件设置资源键,然后使用它在运行时。

扩展器组件的代码在文末。

用法

确保您有资源文件。例如属性文件夹中的Resources.resx。还要确保资源文件中有一些资源键/值。例如,值为“Value1”的 Key1,值为“Value2”的 Key2。那么:

  1. 在您的表单上放置一个ControlTextExtender 组件。
  2. 使用属性网格将其 ResourceClassName 属性设置为资源文件的全名,例如 WindowsApplication1.Properties.Resources`
  3. 选择要设置其Text 的每个控件,并使用属性网格将ResourceKey on controlTextExtender1 属性的值设置为所需的资源键。

然后运行应用程序并查看结果。

结果

这是结果的屏幕截图,如您所见,我什至以这种方式本地化了表单的 Text 属性。

在运行时切换文化

您可以在运行时在文化之间切换,而无需关闭并重新打开表单,只需使用:

System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fa");
this.controlTextExtender1.EndInit();

实施

这是该想法的基本实现:

[ProvideProperty("ResourceKey", typeof(Control))]
public class ControlTextExtender 
    : Component, System.ComponentModel.IExtenderProvider, ISupportInitialize
{
    private Hashtable Controls;
    public ControlTextExtender() : base() { Controls = new Hashtable(); }

    [Description("Full name of resource class, like YourAppNamespace.Resource1")]
    public string ResourceClassName { get; set; }

    public bool CanExtend(object extendee)
    {
        if (extendee is Control)
            return true;
        return false;
    }

    public string GetResourceKey(Control control)
    {
        return Controls[control] as string;
    }

    public void SetResourceKey(Control control, string key)
    {
        if (string.IsNullOrEmpty(key))
            Controls.Remove(control);
        else
            Controls[control] = key;
    }

    public void BeginInit() { }

    public void EndInit()
    {
        if (DesignMode)
            return;

        var resourceManage = new ResourceManager(this.ResourceClassName, 
                                                 this.GetType().Assembly);
        foreach (Control control in Controls.Keys)
        {
            string value = resourceManage.GetString(Controls[control] as string);
            control.Text = value;
        }
    }
}

【讨论】:

  • 这适用于控件,但不适用于工具条项目、datagridview 列和嵌入在其他控件中的控件,我该如何解决这个问题?
  • @Smith 如果你看一下代码的逻辑,你会发现我们只是为Control 对象提供了ResourceKey 属性。那是因为我们要为它们设置Text 属性。但是,如果我们决定也扩展Component 类,如ToolTip,其基类与Control 不同,我们不能依赖Text 属性的存在。对于DataGridViewColumn 类型,据我所知,您无法创建在列集合编辑器中也可以使用的扩展器组件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-24
  • 2016-12-18
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
相关资源
最近更新 更多