如何在设计时从资源文件中将文本设置为控件?

时间:2015-11-27 00:20:45

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

我想知道在设计时是否存在从资源文件设置控件的 cell.scorecardCellImage.file = scorecardData[indexPath.row].scorecardImage cell.scorecardCellImage.loadInBackground() 属性的方法:

Set Property

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

1 个答案:

答案 0 :(得分:5)

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

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

一般情况下,我建议使用Localizable的{​​{1}}和Language Form属性来使用Windows窗体的标准localization机制。

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

扩展程序组件的代码位于帖子的末尾。

用法

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

  1. 在表单上放置一个ControlTextExtender组件。
  2. 使用属性网格将其ResourceClassName属性设置为资源文件的全名,例如WindowsApplication1.Properties.Resources` enter image description here
  3. 选择要设置其Text的每个控件,并使用属性网格将ResourceKey on controlTextExtender1属性的值设置为所需的资源键。 enter image description here
  4. 然后运行应用程序并查看结果。

    <强>结果

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

    enter image description here

    enter image description here

    在运行时在文化之间切换

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

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