【WinForm.NET开发】自定义控件的设计时属性

发布时间:2024年01月10日

本文内容

  1. 定义属性
  2. 序列化属性
  3. 默认值
  4. 类型转换器
  5. 类型编辑器

本文介绍如何在 Visual Studio 的 Windows 窗体视觉对象设计器中为控件处理属性。

每个控件从基类?System.Windows.Forms.Control?继承许多属性,例如:

创建控件时,可以定义新属性并控制它们在设计器中的显示方式。

1、定义属性

具有由控件定义的?get?访问器的任何公共属性都会在 Visual Studio?属性窗口中自动显示。 如果该属性还定义了?set?访问器,则可以在“属性”窗口中更改该属性。 但是,可以通过应用?BrowsableAttribute,在”属性”窗口中显式显示或隐藏属性。 此属性采用单个布尔参数来指示是否显示它。

[Browsable(false)]
public bool IsSelected { get; set; }

[注意] 无法与字符串之间隐式转换的复杂属性需要类型转换器。

2、序列化属性

控件上设置的属性将序列化为设计器的代码隐藏文件。 当属性的值设置为默认值以外的其他值时,将发生这种情况。

当设计器检测到对属性的更改时,它将计算控件的所有属性,并序列化其值与该属性的默认值不匹配的任何属性。 属性的值序列化为设计器的代码隐藏文件。 默认值可帮助设计器确定应序列化哪些属性值。

3、默认值

当属性应用?DefaultValueAttribute?特性或属性的类包含属性特定的?Reset?和?ShouldSerialize?方法时,该属性被视为具有默认值。?

通过设置默认值,可以启用以下内容:

  • 如果已将属性的值修改为非默认值,则该属性会在“属性”窗口中提供视觉指示。
  • 用户可以右键单击该属性,然后选择“重置”,将属性还原为其默认值。
  • 设计器生成更高效的代码。

如果属性使用简单类型(如基元类型),则可以通过将默认值应用于?DefaultValueAttribute?属性来设置。 但是,具有此特性的属性不会自动以该赋值开头。 必须将属性的支持字段设置为相同的默认值。 可以在声明或类的构造函数中设置属性。

当属性是复杂类型,或者想要控制设计器的重置和序列化行为时,请定义类的?Reset<PropertyName>?和?ShouldSerialize<PropertyName>?方法。 例如,如果控件定义?Age?属性,则方法命名为?ResetAge?和?ShouldSerializeAge

?重要

应用?DefaultValueAttribute?到属性,或提供?Reset<PropertyName>?和?ShouldSerialize<PropertyName>?方法。 不要同时使用这两者。

可以右键单击属性名称并选择“重置”,通过“属性”?窗口将属性“重置”为默认值。

40bca472f7d121df6bca27878c0a2931.png

在以下情况下启用“属性”>右键单击>“重置”上下文菜单选项的可用性:

  • 该属性应用了?DefaultValueAttribute?特性,并且属性的值与特性的值不匹配。
  • 该属性的类定义没有?ShouldSerialize<PropertyName>?的?Reset<PropertyName>?方法。
  • 该属性的类定义?Reset<PropertyName>?方法,并且?ShouldSerialize<PropertyName>?返回 true。

3.1 DefaultValueAttribute

如果属性的值与?DefaultValueAttribute?提供的值不匹配,则属性视为已更改,但可通过“属性”窗口重置。

?重要

此特性不应该用于具有相应?Reset<PropertyName>?和?ShouldSerialize<PropertyName>?方法的属性。

以下代码声明两个属性:默认值为?North?的枚举和默认值为 10 的整数。

[DefaultValue(typeof(Directions), "North")]
public Directions PointerDirection { get; set; } = Directions.North;

[DefaultValue(10)]
public int DistanceInFeet { get; set; } = 10;

3.2 重置和 ShouldSerialize

如前所述,Reset<PropertyName>?和?ShouldSerialize<PropertyName>?方法不仅可用于指导属性重置行为,还可用于确定值是否已更改以及应序列化为设计器的代码隐藏文件。 这两种方法协同工作,不应定义一种而不定义另一种。

?重要

不应为具有?DefaultValueAttribute?的属性创建?Reset<PropertyName>?和?ShouldSerialize<PropertyName>?方法。

定义?Reset<PropertyName>?时,“属性”窗口显示该属性的“重置”上下文菜单选项。 选择“重置”时,将调用?Reset<PropertyName>?方法。?“重置”上下文菜单选项由?ShouldSerialize<PropertyName>?方法返回的内容启用或禁用。 当?ShouldSerialize<PropertyName>?返回?true?时,它指示属性已从其默认值更改,应序列化为代码隐藏文件,并启用“重置”上下文菜单选项。 返回?false?时,将禁用“重置”上下文菜单选项,并且代码隐藏已删除属性集代码。

?提示

这两种方法都可以且应该使用专用范围进行定义,以便它们不会构成控件的公共 API。

以下代码片段声明一个名为?Direction?的属性。 此属性的设计器行为由?ResetDirection?和?ShouldSerializeDirection?方法控制。

public Directions Direction { get; set; } = Directions.None;

private void ResetDirection() =>
    Direction = Directions.None;

private bool ShouldSerializeDirection() =>
    Direction != Directions.None;

4、类型转换器

虽然类型转换器通常将一种类型转换为另一种类型,但也为属性网格和其他设计时控件提供字符串到值的转换。 字符串到值的转换允许在这些设计时控件中表示复杂属性。

大多数内置数据类型(数字、枚举和其他类型)都有提供字符串到值转换和执行验证检查的默认类型转换器。 默认类型转换器位于?System.ComponentModel?命名空间中,以转换的类型命名。 转换器类型名称使用以下格式:{type name}Converter。 例如?StringConverterTimeSpanConverter?和?Int32Converter

类型转换器在设计时与“属性”窗口广泛结合使用。 可以使用?TypeConverterAttribute?将类型转换器应用于属性或类型。

在属性上声明?TypeConverterAttribute?时,“属性”窗口使用转换器将属性显示为字符串值。 在类型上声明?TypeConverterAttribute?时,“属性”窗口对该类型的每个属性使用转换器。 类型转换器还有助于序列化设计器的代码隐藏文件中的属性值。

5、类型编辑器

当属性的类型为内置类型或已知类型时,“属性”窗口自动对属性使用类型编辑器。 例如,布尔值被编辑为?True?和?False?值的组合框,DateTime?类型使用日历下拉列表。

文章来源:https://blog.csdn.net/m0_51887793/article/details/135491051
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。