C# WinForms。在组件中实现属性“名称”

Posted

技术标签:

【中文标题】C# WinForms。在组件中实现属性“名称”【英文标题】:C# WinForms. Implementing the property "Name" in the component 【发布时间】:2018-02-25 21:04:42 【问题描述】:

我想在Component 中实现属性Name,它的值与指向组件的表单中的字段名称相同。

 private MyComponent myComponent1;
 this.myComponent1.Name = "myComponent1";

WinForms 已经在 Control 类中实现了这样的属性,但我不明白它是如何工作的。

 private System.Windows.Forms.Button button1;
 this.button1.Name = "button1";

我考虑在 MyComponentDesigner 中声明私有字符串 Name 属性。 或者在 IComponentChangeService 服务中使用 ComponentRename 事件。 探索WinForms的源码并没有给出确切的解释。

【问题讨论】:

【参考方案1】:

对于喜欢 VB 的其他人(比如我),代码如下:

Private _name As String
<Browsable(False)>
Public Property Name As String
    Get
        If Site IsNot Nothing Then _name = Site.Name
        Return _name
    End Get
    Set(ByVal value As String)
        If Site IsNot Nothing Then Site.Name = value
        _name = value
    End Set
End Property

现在,我又添加了一行,以便在很早之前(在设置名称之前)调用名称时不会得到空响应。这是我的代码:

Private _name As String
<Browsable(False)>
Public Property Name As String
    Get
        If Site IsNot Nothing Then
            _name = Site.Name
            If _name = String.Empty Then Return ToString()
        End If
        Return _name
    End Get
    Set(ByVal value As String)
        If Site IsNot Nothing Then Site.Name = value
        _name = value
    End Set
End Property

【讨论】:

【参考方案2】:

如果您只想在属性网格中显示一个简单的Name 属性,只需向您的组件添加一个简单的自动获取设置Name 属性就足够了。但是,如果您希望您的组件具有Name 属性并且(Name) 属性的行为类似于控件的(Name) 属性,请以这种方式添加Name 属性:

string name;
[Browsable(false)]
public string Name

    get
    
        if (Site != null)
            name = Site.Name;
        return name;
    
    set
    
        if (Site != null)
            Site.Name = value;
        name = value;
    
 

这样,您可以使用代码或在属性网格中获取或设置Name 属性。在属性网格中,当您为(Name) 分配值时,它将分配Name 属性,并且设计器也会生成组件名称分配。

【讨论】:

谢谢雷扎。它按预期工作。属性名称由指向 myComponent 的字段的名称分配。但是你能解释一下为什么会这样,或者给出一个解释它的链接。对我来说,它看起来像一个神奇的代码。我尝试通过调试 devenv.exe 来调试 Names.Set 方法。但似乎在设计时从未调用过 Names.Set。 不客气 :) Windows 窗体中的实现基于ControlName 属性、Name 属性和ControlDesignerPrefilterProperties 方法。我没有尝试实现整个模式,而是尝试提供一个对我有用的更简单的实现。在我的实现中,私有 name 字段可帮助您的组件在运行时命名(如果您可以创建 Component 而不将容器传递给其构造函数)。还设置 Site.Name 为您带来设计时所需的行为,就像 Control 类具有此行为一样。 它变得更加清晰,但并不完全。主要工作在 Name.get 方法中完成。当 VS 在代码中实现 Name 方法并从 Name 属性中取值时。在设计时站点! = null,则代码名称 = Site.Name 将起作用; Site.Name 是指向组件的字段的真实属性名称。结果,代码会写下来 this.myComponent1.Name = VS.myComponent1.Name.get (return Site.Name) = "myComponent1"; 那么 Name.set 呢。代码是什么 - if (Site! = null) Site.Name = value; - 为了?在 Name.set 方法中。当我调试 devenv.exe 时,Name.set 方法看起来从未调用过。 在设计时它似乎不是必需的,但对于运行时,如果你从 setter 中删除 if (Site != null) Site.Name = value;,那么在运行时以这种方式创建一个组件 var c = new Component1(components); c.Name = "XXX"; MessageBox.Show(c.Name); 名称将是空的!这就是我添加那行代码的原因。

以上是关于C# WinForms。在组件中实现属性“名称”的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 1.5 组件中实现组件 require 属性

有没有一种简单的方法可以在 WinForms 中实现 Checked Combobox [重复]

在组件的持久化中实现 `Auto` 属性

如何在自定义 delphi 组件中实现 stringlist 属性?

数组如何实现 IList<T> 而无需在 C# 中实现属性“Count”? [复制]

Winforms:在设计器中创建对象并对其进行自定义