簡體   English   中英

在自定義TextBox控件的構造函數中添加Validating事件處理程序

[英]Add Validating event handler in constructor of a custom TextBox control

我創建了一個繼承自TextBox的自定義控件。

我有一個ValidateTextBoxEntry方法,由Validating事件調用。

通常,我會使用可視化編輯器中的屬性編輯器將ValidateTextBoxEntry添加到自定義控件的每個實例的Validating事件中。

相反,我寧願在自定義控件的構造函數中自動添加一行到所有事件處理程序,如下所示:

    public CustomTextBox()
    {
        InitializeComponent();
        this.Validating += 
        new System.ComponentModel.CancelEventHandler(ValidateTextBoxEntry);
   }

將Validating事件處理程序添加到自定義控件的所有實例的優雅方法是什么?

    this.Validating += 
    new System.ComponentModel.CancelEventHandler(ValidateTextBoxEntry);

這不優雅。 .NET中的事件是Observer Pattern的一個實現。 您公開它們,以便其他代碼可以訂閱事件,在這種情況下,自定義驗證。 必須傾聽自己的事件是沒有意義的。

為了適應,每個Xxxx事件都有一個OnXxxx()方法。 您可以自己調用此方法以引發Validating事件。 或者,更常見的是,在這種情況下,您可以將其留給Winforms來為您調用它。 示例實現可能如下所示:

    protected override void OnValidating(CancelEventArgs e) {
        if (this.Text.Length == 0) e.Cancel = true;
        else base.OnValidating(e);
        DisplayWarning(e.Cancel);
    }

請注意如何在此處自定義事件處理。 它實現了一個規則,即在文本框中有一個空字符串永遠不會有效。 此時沒有理由再調用base.Onvalidating(),您不希望事件處理程序覆蓋該規則。 並通過自動處理向用戶顯示他的數據輸入需要處理的提示進一步擴展。

這樣做可以讓您控制代碼運行的順序,這非常重要。

我同意elgonzo的評論,這可能不是正確的方法,但我認為你可以通過interface實現它。

如果定義包含處理程序定義的接口並使每個表單實現該接口,則可以從控件中連接處理程序(如果可以找到正確的表單)。 為此,您可以繼續迭代Parent屬性,直到它為空。 我真的不認為這是值得的努力:

//the interface
public interface IShouldntDoThis
{
    void MyTextBox_Validating(object sender, CancelEventArgs e);
}

//the control
public class MyTextBox : TextBox
{
    public MyTextBox()
    {

    }

    protected override void InitLayout()
    {
        base.InitLayout();

        Control parent = this.Parent;
        while (parent.Parent != null)
        {
            parent = parent.Parent;
        }

        //parent should now be the Form
        IShouldntDoThis test = parent as IShouldntDoThis;
        if (test != null)
        {
            this.Validating += test.MyTextBox_Validating;
        }
    }
}

//the form
public partial class MainForm : Form, IShouldntDoThis
{
    public Form1()
    {
        InitializeComponent();
    }

    public void MyTextBox_Validating(object sender, CancelEventArgs e)
    {
        throw new NotImplementedException();
    }
}

好吧,事實證明,在構造函數中添加一行(正如我在問題中所示), 正確的方法(如elgonzo所述 - 謝謝)。

關鍵是使事件處理程序成為類本身的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM