65.9K
CodeProject 正在变化。 阅读更多。
Home

自定义控件库(MaskEdit、带进度面板的状态栏等)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (13投票s)

2004年6月1日

5分钟阅读

viewsIcon

87448

downloadIcon

3176

自定义控件库(MaskEdit、带进度面板的状态栏等)。

Sample Image - CustomControls.gif

引言

CustomControls.dll 中提供了两个控件。要使用它们,只需添加对 DLL 的引用,您应该会在工具箱中看到这两个控件(TextBoxExStatusBarEx)。

TextBoxEx 是标准 TextBox 的扩展。它支持

  • 掩码、(掩码字符集中,# = 数字,A = 所有大写字母,a = 所有小写字母,$ = #,A,a,& = A,a)
  • 正则表达式验证(自定义和一些内置的),
  • 仅字母验证,
  • 仅数字验证,
  • 用户自定义字符/数字验证,
  • 内置 ErrorProvider
  • 可以使用 ENTER 键代替 TAB。 (这对于数据录入类应用程序非常方便。)

StatusBarEx 是标准 StatusBar 的扩展。它支持 4 种面板类型。

  • 日期面板,
  • 时间面板,
  • 平滑进度条面板,
  • 图案进度条面板(这个只是一个花哨的)。

参考文献

我一直在寻找验证控件,找到了 Luis Alberto Ruiz Arauz 的 ValidText 控件(在 CodeProject 上发布)。因为我想要一个 C# 版本的,所以我打算将代码转换为 C# 并包含一些改进(下面讨论)。

平滑进度条的创意来自 Microsoft KB 文章 323116。

因此,也应该感谢那些与我们分享知识的人。同样,如果有人使用此代码并进行了任何修复/改进,请告知我。

我仅在 Windows 2000 上测试过此代码。但由于它仅依赖于 .NET 运行时,我认为它在其他操作系统上也能很好地工作。

TextBoxEx 的代码说明

TextBoxEx 控件的 MaskEdit 功能与 Luis 的 VB.NET 版本相比,采用了截然不同的方法。因此,我设法删减了大量代码,保留了相同的功能并修复了一些错误。

基类 TextBoxKeyPress 事件已被重写,所有掩码验证都在 PerformMaskValidation 方法中完成。在此方法中,对于每个掩码字符(#、A、a、%、$),将使用 IsValidInputForMask 检查有效数据。当 TextBoxEx 控件在 Mask 模式下工作时,您不能半填充掩码然后离开控件。如果您希望将其留空,可以通过不输入任何数据来实现。(但是,如果 IsRequired 属性设置为 true,则在验证时会提示输入数据)。这意味着,对于像 (###)-AA-aa 这样的掩码

  • 如果 IsRequired=true,则掩码**必须**填写。
  • 如果 IsRequired=false,则掩码可以留空。但是,您不能半填充然后尝试离开控件。

TextBoxExMask 模式下会捕获 SHIFT-INSERT、CTRL-V(粘贴)和上下文菜单等组合键,以便一旦设置了掩码,您将无法在运行时通过将任何值设置到 Text 属性来意外清除它。为了捕获此键盘输入,我重写了 ProcessCmdKey 事件。如果您尝试通过为 Text 属性分配某个值来覆盖掩码,它们仍然会被验证。例如,如果掩码是 (###)-AA,并且您分配 txtBoxEx.Text="AB12CDEF"Text 属性将仅包含 (12_)-__。(掩码从左到右填充。在这里,输入字符串只有 2 个数字,而掩码需要 3 个。因此,它接受 2 个数字并丢弃其余的。)通过这种方式,可以避免破坏掩码并抛出异常(这是其他控件会发生的情况)。因此,如果您需要在运行时重置掩码,您必须这样做

txtBoxEx.ValidationText="(###)-AA"; //your new mask string
txtBoxEx.Text="123AB"; //data

此外,如果您想一次性验证所有 TextBoxEx 控件(例如,在将数据添加到数据库之前验证整个窗体的 TextBoxEx 控件),您可以使用公共 Validate() 方法。在示例应用程序中,这在 btnValidateAll_Click() 方法中显示。

    private void btnValidateAll_Click(object sender, System.EventArgs e)
    {
        bool allValid=true;

        allValid = RecursiveControlValidation(this);

        if (allValid)
            MessageBox.Show(this,"All controls contain valid data");
        else
            MessageBox.Show(this, 
                "Indicated controls contain invalid/incomplete data");
    }

    private bool RecursiveControlValidation(Control ctl)
    {
        bool isValid=true;

        if (ctl.HasChildren)
        {
            foreach(Control c in ctl.Controls)
            {
                isValid &=RecursiveControlValidation(c);
            }
        }
        if(ctl.GetType()==typeof(CustomControls.TextBoxEx))
        {
            if ( !((CustomControls.TextBoxEx)ctl).Validate() )
            {
                isValid =false;
            }
        }
        return isValid;
    }

包含的另一个有用选项是按下 ENTER 键即可移动到下一个控件。这听起来可能不重要,但我在几个项目中遇到过,所有数据录入人员都坚持要求使用 ENTER 键来移动到下一个文本框。(实际上,对于数据录入来说,这比使用 TAB 容易。)在标准的 TextBox 中,您需要为此附加一个事件。但在 TestBoxEx 中,将属性 UseEnterAsTab 设置为 true 即可完成其余工作。我使用的代码是

    protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
    {
        if (useEnterAsTab)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SendKeys.Send("{Tab}");
                e.Handled=true;
            }
        }
        base.OnKeyDown(e);
    }

代码本身包含一些其他有用的注释。如果您要修改代码,这些注释可能会对您有所帮助。


StatusBarEx 的代码说明

因为 StatusBarEx 应该支持带有进度条的面板,所以标准的 StatusBarPanel 已扩展为 StatusBarPanelEx。为了能够在设计时将 StatusBarPanelEx 添加到 StatusBarEx,已实现了一个设计时 CollectionEditor。此代码位于 StatusBarPanelExCollectionEditor 类中。常规的 StatusBarPanelCollection 已被 StatusBarPanelExCollection 类覆盖。该类返回 StatusBarPanelEx 类型。StatusBarEx 中的 Panels 属性被定义为使用新的 StatusBarPanelExCollectionEditor 而不是标准的 CollectionEditor。(否则,它在设计时只会添加 StatusBarPanel 类型。)使用哪种类型编辑器已通过以下属性进行设计

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(System.ComponentModel.Design.CollectionEditor), 
                  typeof(System.Drawing.Design.UITypeEditor))]
[Editor(typeof(StatusBarPanelExCollectionEditor),
                  typeof(System.Drawing.Design.UITypeEditor))]
public new StatusBarPanelExCollection Panels
{
}

待办事项

TextBoxEx 中,如果有人需要将掩码字符(A、a、$、&、#)保留为普通字符,则它们应该从掩码中转义。我将很快添加此功能。目前,如果您的掩码是 (###)-AA,它将被翻译为 (___)-__。但是,如果您想将上述任何掩码字符保留为普通字符呢?我将使用转义序列,因此如果您需要,可以指定像 (##\#)-A\A 这样的掩码,它将被翻译为 (__#)-_A。

此外,我将在库中添加几个我为我的项目开发的控件。目前,在获取自定义设计器正常工作方面遇到了一些麻烦。你们有人知道如何监控 Visual Studio 中的 Component Tray 以了解组件的添加/删除吗?如果知道,请告诉我。

© . All rights reserved.