从自定义控件的另一个属性获取在设计器中设置的属性值

问题描述

我创建了“自定义控件”,并添加一个属性,该属性旨在指向“资源”。
如何从“自定义控件”的另一个属性获取属性的值,该值是在“表单设计器”中设置的? 当我尝试读取它时,它返回的值为null

enter image description here

我的代码与“自定义控件”和上述属性有关:

class ResourceLabel : Label
{
    private string resourceKey;
    
    [Category("Appearance")]
    [browsable(true)]
    [Description("Sets the resource key for localization")]
    public string ResourceKey
    {
        get { return resourceKey; }
        set {
            if (resourceKey != value) {
                resourceKey = value;
                Invalidate();
            }
        }
    }

    [browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [Editorbrowsable(EditorbrowsableState.Always)]
    [Bindable(true)]
    public override string Text
    {
        if (base.Text != value) {
            Console.WriteLine($"Test: {ResourceKey}");

            if (ResourceKey != null) {
                var locale = CultureInfo.GetCultureInfo(Properties.Settings.Default.Language);
                var textFromresource = Resources.ResourceManager.GetString(ResourceKey,locale);
                base.Text = textFromresource;
            } 
            else {
                base.Text = value;
            }
        }
    }
}

此字符串Console.WriteLine($"Test: {ResourceKey}");返回null

解决方法

鉴于问题的描述以及应用于自定义控件的 Description 属性的ResourceKey属性,看来您正在本地化应用程序,设置-因此,父表单的 Localizable 属性为true

这会更改窗体初始化中的一些细节。
如果查看Form.Designer.cs文件,您会注意到已添加了一些新部件:
通常:
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(YourForm));

现在有了新的同伴。在每个控件的初始化部分,添加了 resources.ApplyResources(this.controlName,"controlName");

您的自定义标签应显示,例如:

resources.ApplyResources(this.resourceLabel1,"resourceLabel1");

Control派生的许多标准属性都可以本地化(用 [Localizable(true)] 属性修饰)。 Text property is of course among these。这些属性的值现在存储在用于不同本地化的资源文件中。因此,这些属性不再在Designer.cs文件中设置,而是在其他属性之前初始化。

您的 ResourceKey 属性未定义为Localizable,因此将其添加到Designer.cs文件中并在可本地化属性之后进行初始化。

►一个简单的解决方法是将ResourceKey属性定义为Localizable,以便将其与Text属性一起在非本地化属性之前进行初始化。

[Localizable(true),Browsable(true)]
[Category("Appearance"),Description("Sets the resource key for localization")]
public string ResourceKey {
    get { return resourceKey; }
    set {
        if (resourceKey != value) {
            resourceKey = value;
            Invalidate();
        }
    }
}

请注意,这是一个重大更改,您应该:

1-将Localizable属性添加到ResourceKey属性中
2-从表单设计器中删除 old ResourceLabel控件
3-编译解决方案
4-将自定义ResourceLabel添加回原来的位置
5-在“属性面板”中设置所需控件的属性
6-运行应用程序或编译项目

检查表单的Designer.cs文件,查看ResourceKey属性是否消失,现在通过resources.ApplyResource()设置其值。

►如果您不想使该属性可本地化,则必须在控件的初始化完成后读取其值以后。例如,覆盖OnHandleCreated方法。请注意,在少数情况下可以在运行时重新创建控件的句柄(设置需要控件重新创建句柄的关键属性)。

注意
您不应该依赖于属性的初始化顺序,不能真正保证一个属性先于另一个被初始化。设计控件的行为时要考虑到这一点。