【WinForm.NET开发】自定义控件的设计时属性
本文内容
- 定义属性
- 序列化属性
- 默认值
- 类型转换器
- 类型编辑器
本文介绍如何在 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>
?方法。 不要同时使用这两者。
可以右键单击属性名称并选择“重置”,通过“属性”?窗口将属性“重置”为默认值。
在以下情况下启用“属性”>右键单击>“重置”上下文菜单选项的可用性:
- 该属性应用了?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
。 例如?StringConverter、TimeSpanConverter?和?Int32Converter。
类型转换器在设计时与“属性”窗口广泛结合使用。 可以使用?TypeConverterAttribute?将类型转换器应用于属性或类型。
在属性上声明?TypeConverterAttribute
?时,“属性”窗口使用转换器将属性显示为字符串值。 在类型上声明?TypeConverterAttribute
?时,“属性”窗口对该类型的每个属性使用转换器。 类型转换器还有助于序列化设计器的代码隐藏文件中的属性值。
5、类型编辑器
当属性的类型为内置类型或已知类型时,“属性”窗口自动对属性使用类型编辑器。 例如,布尔值被编辑为?True?和?False?值的组合框,DateTime?类型使用日历下拉列表。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!