C# 数字字段控件
数字字段控件的抽象基类。
 
 
引言
在创建了 .NET Framework 的 IP 地址控件 之后,我将学到的经验应用于创建一个抽象控件。此控件可以轻松配置,以允许输入任何由数字字段集合组成的值,例如 IP 地址、带端口的 IP 地址、IPv6 地址、MAC 地址、电话号码或社会安全号码。
背景
FlexFieldControl 是一个基于 UserControl 的抽象类,它聚合了 n 个 FieldControl 类型的控件和 n+1 个 SeparatorControl 类型的控件。这些控件以交替的方式水平排列,从 SeparatorControl 开始。下面是默认 FlexFieldControl 控件的图像,其中高亮显示了聚合的控件。
 
 
默认情况下,FlexFieldControl 包含三个 FieldControl 和四个 SeparatorControl。按照下面的 API,下面是一个如何通过仅十行代码来扩展 FlexFieldControl 以创建新控件 MACAddressControl 的示例。
Using the Code
一旦包含 FlexFieldControl 的库(FlexFieldControlLib.dll)构建完成,请将该 DLL 添加到您的 Windows Forms 项目的引用中。FlexFieldControl 被定义为 abstract;它不会出现在 Windows Forms 设计器的工具箱中。但是,任何基于 FlexFieldControl 的控件都会出现。
公共实例属性
- AutoHeight- 获取或设置一个值,该值指示控件是否根据当前字体和边框自动垂直调整大小。默认值为- true
- Blank- 获取一个值,该值指示控件中的所有字段是否为空
- BorderStyle- 获取或设置控件的边框样式。默认值为- BorderStyle.Fixed3D
- FieldCount- 获取或设置控件中的字段数量。默认值为- 3,最小值为- 1。设置此值会重置每个字段和分隔符到其默认状态。
- ReadOnly- 获取或设置一个值,该值指示控件的内容是否可以更改。
- Text- 获取或设置控件的文本。
公共实例方法
- AddCedeFocusKey- 为一个字段添加一个特定的按键,该按键会将焦点转移到控件中的下一个字段。默认情况下,[空格键] 会为任何非空的字段转移焦点。
- Clear- 清除控件中所有字段的所有文本。
- ClearCedeFocusKeys- 移除字段中导致焦点转移的所有按键。
- GetCasing- 获取控件中字段的字符大小写。默认值为- CharacterCasing.Normal。
- GetFieldText- 获取控件中字段的文本。
- GetLeadingZeros- 获取一个非空字段是否具有前导零。默认值为- false。
- GetMaxLength- 获取字段允许的最大字符数。默认值为- 3。
- GetRangeHigh- 获取字段允许的最大值。默认值基于字段的最大长度和值格式。
- GetRangeLow- 获取字段允许的最小值。默认值为- 0。
- GetSeparatorText- 获取控件中分隔符的文本。
- GetValue- 获取控件中字段的值。如果字段为空,则其值为其低范围值。
- GetValueFormat- 获取控件中字段的值格式。默认值为- ValueFormat.Decimal。
- HasFocus- 获取控件中字段是否具有输入焦点。
- IsBlank- 获取控件中字段是否为空。
- ResetCedeFocusKeys- 将字段重置为其默认的焦点转移键,即 [空格键]。
- SetCasing- 设置控件中字段的字符大小写。- CharacterCasing.Lower会最小化具有- ValueFormat.Hexadecimal值格式的字段的水平尺寸。
- SetFieldText- 设置控件中字段的文本。
- SetFocus- 将输入焦点设置为控件中的一个字段。
- SetLeadingZeros- 设置一个非空字段是否具有前导零。
- SetMaxLength- 设置字段允许的最大字符数。最小值为- 1;最大值取决于值格式:十进制值为- 9个字符,十六进制值为- 7个字符。
- SetRange- 设置控件中字段允许的最小值和最大值。
- SetSeparatorText- 设置控件中分隔符的文本。
- SetValue- 设置控件中字段的值。
- SetValueFormat- 设置控件中字段的值格式。
- ToString- 获取控件的文本。如果任何字段为空,则该字段的文本将是其低范围值。
该client(客户端)代码可以为公共事件 FieldChangedEvent 注册一个处理程序,以便在控件中任何字段的文本发生更改时收到通知。另一个公共事件 FieldValidatedEvent 会在任何字段的文本得到验证时发出通知。请注意,Text 和 ToString() 可能不会返回相同的值。如果控件中有任何空字段,Text 将返回反映空字段的值。ToString() 会用该字段的低范围值填充任何空字段。
创建 MACAddressControl
这是创建简单的 MACAddressControl 的源代码。
using System;
using System.Windows.Forms;
using FlexFieldControlLib;
namespace TestFlexFieldControl
{
    class MACAddressControl : FlexFieldControl
    {
        public MACAddressControl()
        {
            // the format of this control is 'FF:FF:FF:FF:FF:FF'
            // set FieldCount first
            //
            FieldCount = 6;
            // every field is 2 digits max
            //
            SetMaxLength( 2 );
            // every separator is ':'...
            //
            SetSeparatorText( ":" );
            // except for the first and last separators
            //
            SetSeparatorText( 0, String.Empty );
            SetSeparatorText( FieldCount, String.Empty );
            // the value format is hexadecimal
            //
            SetValueFormat( ValueFormat.Hexadecimal );
            // use leading zeros for every field
            //
            SetLeadingZeros( true );
            // use uppercase only
            //
            SetCasing( CharacterCasing.Upper );
            // add ':' key to cede focus for every field
            //
            KeyEventArgs e = new KeyEventArgs( Keys.OemSemicolon );
            AddCedeFocusKey( e );
            // this should be the last thing
            //
            Size = MinimumSize;
        }
    }
}
构造函数中的第一步应该是始终设置控件的 FieldCount。否则,任何先前的设置都将被重置。例如,如果每个字段的值格式都设置为 ValueFormat.Hexadecimal,然后更改了 FieldCount,则每个字段的值格式都会重置为其默认值 ValueFormat.Decimal。
下一步是设置每个字段允许的最大字符数。在这种情况下,每个字段都通过 SetMaxLength( 2 ) 设置为相同的最大长度。或者,可以单独设置每个字段:SetMaxLength( 0, 2 )、SetMaxLength( 1, 2 )、SetMaxLength( 2, 2 ) 等。SetMaxLength 中的第一个参数是控件中字段的零基索引。
默认情况下,每个分隔符的文本根据其在控件中的位置,分别为 "<"、"><" 或 ">"。对于此 MACAddressControl,除了第一个和最后一个分隔符外,每个分隔符的文本都是 ":"。SetSeparatorText( ":" ) 将所有分隔符的文本设置为 ":"。为了清除第一个和最后一个分隔符的文本,调用了 SetSeparatorText( 0, String.Empty ) 和 SetSeparatorText( FieldCount, String.Empty )。
每个字段的默认值格式是 ValueFormat.Decimal,但此控件在每个字段中使用十六进制值。调用 SetValueFormat( ValueFormat.Hexadecimal ) 将控件中的所有字段设置为十六进制值格式。或者,可以调用带字段索引的 SetValueFormat 来设置单个字段的值格式。
由于 MAC 地址通常在每个字段中显示前导零(例如,“08:09:0A:0B:0C:0D”,而不是“8:9:A:B:C:D”),因此通过调用 SetLeadingZeros( true ) 将每个字段设置为显示前导零。或者,可以调用带字段索引的 SetLeadingZeros 来单独设置每个字段的前导零属性。默认情况下,每个字段不显示前导零。
此控件通过调用 SetCasing( CharacterCasing.Upper ) 来强制所有字段中的十六进制字母显示为大写。如果用户在任何字段中输入“a”,控件将在该字段中显示“A”。或者,可以调用带字段索引的 SetCasing 来单独设置每个字段的字符大小写。为了方便用户,此控件将 [;] 键添加为每个字段的焦点转移键,使用
KeyEventArgs e = new KeyEventArgs( Keys.OemSemicolon );
AddCedeFocusKey( e );
如果字段的值可以用一个字符表示,用户可以输入该字符,然后按 [;] 键或 [空格键] 将控件的输入焦点移至下一个字段。或者,可以调用带字段索引的 AddCedeFocusKey 来单独设置每个字段的焦点转移键。
构造函数中的最后一个调用 Size = MinimumSize 会强制控件尽可能小。随着设置的变化,控件只会增长以适应它们;它不会自动收缩。一旦控件放置在窗体上,就可以根据需要调整其大小。
历史
- 2008 年 4 月 29 日- 添加了 PreviewKeyDown、KeyDown和KeyUp事件的传播。
 
- 添加了 
- 2007 年 11 月 20 日- 更改 FieldCount时,添加了在重新创建子控件时调用Dispose()。感谢 Glenn 报告此问题。
 
- 更改 
- 2007 年 10 月 23 日- ReadOnly现在应该真正是只读的。
 
- 2007 年 10 月 4 日- 为某些鼠标事件添加了正确的事件传播。
- 添加了 AnyBlank属性。
- 删除了多余的代码。
- 解决了计算文本大小时潜在的资源泄漏问题。
- 符合 FxCop 1.35。
 
- 2007 年 7 月 23 日- 修复了与设置带前导零的字段文本相关的错误。再次感谢 zeno_nz 报告此问题。
 
- 2007 年 7 月 15 日- GotFocus和- LostFocus事件得到一致引发。
- 添加了 AllowInternalTab属性以允许在控件内进行制表。默认值为false。
 
- 2007 年 6 月 27 日- 对 Text属性的更改在设计模式下得以保留。
- 库的客户端可以捕获 KeyPress事件。感谢 zeno_nz 请求此增强功能。
 
- 对 
- 2007 年 6 月 5 日- 首次发布
 




