如何在项目范围内共享特定于控件的事件处理程序?

时间:2014-11-12 22:29:43

标签: c# winforms delegates event-handling keypress

我可以编写一个事件来将文本框条目限制为十进制值,如下所示:

private void txtbxPlatypus_KeyPress(object sender, KeyPressEventArgs args)
{
    const int BACKSPACE = 8;
    const int DECIMAL_POINT = 46;
    const int ZERO = 48;
    const int NINE = 57;
    const int NOT_FOUND = -1;

    int keyvalue = (int)args.KeyChar; // not really necessary to cast to int

    if ((keyvalue == BACKSPACE) || ((keyvalue >= ZERO) && (keyvalue <= NINE))) return;
    // Allow the first (but only the first) decimal point
    if ((keyvalue == DECIMAL_POINT) && ((sender as TextBox).Text.IndexOf(".") == NOT_FOUND)) return;
    // Allow nothing else
    args.Handled = true;
}

...然后在页面上放置其他TextBox,并将相同的条目过滤要求附加到该事件处理程序:

txtbxSeat.KeyPress += txtbxPlatypus_KeyPress;
txtbxLunch.KeyPress += txtbxPlatypus_KeyPress;

但是,如果我想在项目范围内共享这样的处理程序,而不是必须在每个具有TextBox的页面上重现它,其输入需要以这种方式进行限制?

有没有办法设置可以从项目中的任何表单使用的“全局”(项目范围)事件处理程序委托?

更新

这确实有效:

public static class SandBoxUtils
{
    public static void DecimalsOnlyKeyPress(object sender, KeyPressEventArgs args)
    {
        // same code as above in txtbxPlatypus_KeyPress()
    }
}

public Form1()
{
    InitializeComponent();
    textBoxBaroqueMelodies.KeyPress += new 
        System.Windows.Forms.KeyPressEventHandler(SandBoxUtils.DecimalsOnlyKeyPress);
}

......但它闻起来有点可疑。关于这样做,这有什么“错误”(或危险)?

1 个答案:

答案 0 :(得分:1)

创建从System.Windows.Forms.TextBox派生的自己的类 在构造函数中添加KeyPress事件的事件处理程序 构建项目后,新控件必须出现在Visual Studio的控件工具箱中,
从那里你可以将它拖到表单并使用...

class TextBoxDecimal : System.Windows.Forms.TextBox
{
    const int BACKSPACE = 8;
    const int DECIMAL_POINT = 46;
    const int ZERO = 48;
    const int NINE = 57;
    const int NOT_FOUND = -1;
    const char DECIMALSEPARATOR = '.';     

    public TextBoxDecimal() :base()
    {
        this.KeyPress += TextBoxDecimal_KeyPress;
    }

    void TextBoxDecimal_KeyPress(object sender, 
                                 System.Windows.Forms.KeyPressEventArgs e)
    {
        int keyvalue = (int)e.KeyChar; // not really necessary to cast to int

        if ((keyvalue == TextBoxDecimal.BACKSPACE) || ((keyvalue >= TextBoxDecimal.ZERO) && (keyvalue <= TextBoxDecimal.NINE))) return;
        // Allow the first (but only the first) decimal point
        if ((keyvalue == TextBoxDecimal.DECIMAL_POINT) && ((sender as TextBoxDecimal).Text.IndexOf(TextBoxDecimal.DECIMALSEPARATOR) == NOT_FOUND)) return;
        // Allow nothing else
        e.Handled = true;
    }
}