C#"焦點事件"中的Validating處理方法 收藏
無意中接了個Window的項目,現(xiàn)總結Validating的處理方法,以供以后參考之用。焦點事件按下列順序發(fā)生:
Enter //進入控件時發(fā)生
GotFocus //在控件接收焦點時發(fā)生
Leave //輸入焦點離開控件時發(fā)生
Validating //控件數(shù)據(jù)效驗時發(fā)生
Validated //數(shù)據(jù)效驗完成后發(fā)生
LostFocus //失去焦點時發(fā)生
如果 CausesValidation 屬性設置為 false,則將取消 Validating 和 Validated 事件。
注:GotFocus 和 LostFocus 事件是關聯(lián)于 WM_KILLFOCUS 和 WM_SETFOCUS Windows 消息的低級別焦點事件。應對所有控件使用 Enter 和 Leave 事件。
如果在 Validating 事件委托中,CancelEventArgs 對象的 Cancel 屬性設置為 true,則正常情況下將在 Validating 事件之后發(fā)生的所有事件均被取消。
在操作中驗證
要驗證控件的內(nèi)容,可以編寫代碼來處理 Validating 事件。在事件處理程序中,測試特定的條件(例如上面的電話號碼)。驗證是在處理時發(fā)生的一系列事件之一。
如果測試失敗,則 Validating 事件的 CancelEventArgs 的 Cancel 屬性將設置為 True。這將取消 Validating 事件,并導致焦點返回到控件(juky_huang注:這樣會出現(xiàn)一個死循環(huán),除非數(shù)據(jù)效驗通過,可以使用下面強制方法來關閉)。實際的結果是,除非數(shù)據(jù)有效,否則用戶將無法退出該控件。
關閉窗體和重寫驗證
當數(shù)據(jù)無效時,維護焦點的控件的副作用是,使用關閉窗體的任何常規(guī)方法都將無法關閉父窗體:
單擊“關閉”框
通過右擊標題欄顯示的“系統(tǒng)”菜單
以編程方式調(diào)用 Close 方法
不過,在某些情況下,無論控件中的值是否有效,您都希望用戶可以關閉窗體。您可以重寫驗證,并通過創(chuàng)建窗體的 Closing 事件的處理程序來關閉仍包含無效數(shù)據(jù)的窗體。在該事件中,將 Cancel 屬性設置為 False。這將強制關閉該窗體。
注意 如果使用此方法強制關閉窗體,控件中尚未保存的任何信息都將丟失。
注意 模式窗體在關閉時不會驗證控件內(nèi)容。您仍可以使用控件驗證將焦點鎖定到控件,但不必考慮關閉窗體的行為。
以下是事例代碼:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace MSDNValidatingEx
{
/// <summary>
/// Form1 的摘要說明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.ErrorProvider errorProvider1;
/// <summary>
/// 必需的設計器變量。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 窗體設計器支持所必需的
//
//
// TODO: 在 InitializeComponent 調(diào)用后添加任何構造函數(shù)代碼
//
InitializeComponent();
textBox1.Validating+=new CancelEventHandler(textBox1_Validating); //給textBox1添加效驗函數(shù)
textBox1.Validated+=new EventHandler(textBox1_Validated);
}
private void textBox1_Validating(object sender,CancelEventArgs e)
{
string errorMsg;
if(!ValidEmailAddress(this.textBox1.Text,out errorMsg))
{
//如果效驗沒有通過取消后繼事件,即Validated,LostFocus
e.Cancel=true;
this.textBox1.Select(0,this.textBox1.Text.Length);
this.errorProvider1.SetError(this.textBox1,errorMsg);
}
}
private void textBox1_Validated(object sender,EventArgs e)
{
errorProvider1.SetError(this.textBox1,"");
}
public bool ValidEmailAddress(string emailAddress,out string errorMessage)
{
//首先判斷是否為空,然后判斷是否有@,.符號
if(emailAddress.Length==0)
{
errorMessage="e-mail address is required.";
return false;
}
//是否包含@
if(emailAddress.IndexOf("@")>-1)
{
//從@往后面開始搜索,找到.的位置,如果位置大于@的位置說明格式正確
if(emailAddress.IndexOf(".",emailAddress.IndexOf("@"))>emailAddress.IndexOf("@"))
{
errorMessage="";
return true;
}
}
errorMessage="e-mail address must be valid e-mail address format.\n"+"For example
'someone@example.com'";
return false;
}
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗體設計器生成的代碼
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內(nèi)容。
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.errorProvider1 = new System.Windows.Forms.ErrorProvider();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(72, 88);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 0;
this.textBox1.Text = "";
//
// errorProvider1
//
this.errorProvider1.ContainerControl = this;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 應用程序的主入口點。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}