我在winform上方一个button和一个textbox其中button负责关闭窗体然后textbox的causevalidated属性为默认值true用户在textbox中输入内容点button关闭窗体的时候,由于焦点从textbox向外转移,所以会自动触发textbox的validating事件我现在想实现在点button关闭窗体或直接点窗体右上角关闭按钮关闭窗体的时候不执行textbox的validating事件怎么实现?我看到validating事件中有一个canceleventargs参数是一个事件类型参数能否通过这个参数来判断事件的类型或判断事件是由哪个控件执行的
如果可以判断这个,我就可以在validating事件中进行判断来设置e.cancel的值
如果可以判断这个,我就可以在validating事件中进行判断来设置e.cancel的值
是先TextBox是去焦点,再执行Button事件
帮你顶一下
{
MessageBox.Show("S");
} private const int WM_CLOSE = 0x0010;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_CLOSE)
{
textBox1.CausesValidation = false;
}
base.WndProc(ref m);
} private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void textBox1_Validating(object sender, CancelEventArgs e)
{
e.Cancel = !closing & string.IsNullOrEmpty(((TextBox)sender).Text);
}private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
closing = false;
}protected override void WndProc(ref Message m)
{
const int WM_CLOSE = 0x0010;
switch (m.Msg)
{
case WM_CLOSE:
closing = true;
break;
}
base.WndProc(ref m);
}
private void textBox1_Validating(object sender, CancelEventArgs e)
{
Console.WriteLine("textBox1_Validating");
}private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Console.WriteLine("Form1_FormClosing");
}protected override void WndProc(ref Message m)
{
const int WM_CLOSE = 0x0010;
switch (m.Msg)
{
case WM_CLOSE:
Console.WriteLine("WM_CLOSE");
break;
}
base.WndProc(ref m);
}
WM_CLOSE
textBox1_Validating
Form1_FormClosing
有没有办法可以解决?
/// 定义窗口关闭消息WM_CLOSE
/// </summary>
private const int WM_CLOSE = 0X0010; /// <summary>
/// 重载窗体的WndProc窗口过程
/// </summary>
/// <param name="aMsg"></param>
protected override void WndProc(ref Message aMsg)
{
if (aMsg .Msg ==WM_CLOSE)
{
if (this.txtbxDepaName.CausesValidation == true)
{
this.txtbxDepaName.CausesValidation = false;
}
}
else
{
if (this.txtbxDepaName.CausesValidation == false)
{
this.txtbxDepaName.CausesValidation = true;
}
}
base.WndProc (ref aMsg);
} /// <summary>
/// 焦点离开文本框txtbxDepaName触发校验事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtbxDepaName_Validating(object sender, CancelEventArgs e)
{
if (txtbxDepaName.Text.Trim().Length > 0)
{
if (gIntfDataValidator.IsChineseCharacter(this.txtbxDepaName.Text.Trim()) == false)
{
e.Cancel = true; //不要使用txtbxDepaName.Focus();,效率低
}
}
} /// <summary>
/// 点击按钮【关闭】关闭当前部门添加界面
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnClose_Click(object sender, EventArgs e)
{
gFrmController.CloseForm(this);
}
{
if (this.txtbxDepaName.CausesValidation == true)
{
this.txtbxDepaName.CausesValidation = false;
}
}
else
{
if (this.txtbxDepaName.CausesValidation == false)
{
this.txtbxDepaName.CausesValidation = true;
}
} 窗体关闭的时候除了WM_CLOSE还有其他消息,你这个else写得太想当然了。private void textBox1_Validating(object sender, CancelEventArgs e)
{
e.Cancel = string.IsNullOrEmpty(((TextBox)sender).Text);
}private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
textBox1.CausesValidation = true;
}protected override void WndProc(ref Message m)
{
const int WM_CLOSE = 0x0010;
switch (m.Msg)
{
case WM_CLOSE:
textBox1.CausesValidation = false;
break;
}
base.WndProc(ref m);
}
{
if (aMsg .Msg ==WM_CLOSE)
{
if (this.txtbxDepaName.CausesValidation == true)
{
this.txtbxDepaName.CausesValidation = false;
}
}
else
{
if (this.txtbxDepaName.CausesValidation == false)
{
this.txtbxDepaName.CausesValidation = true;
}
}
base.WndProc (ref aMsg);
} 我在最后是由集成基类窗口过程的语句的
if (aMsg .Msg ==WM_CLOSE)
{
if (this.txtbxDepaName.CausesValidation == true)
{
this.txtbxDepaName.CausesValidation = false;
}
}
else
{
if (this.txtbxDepaName.CausesValidation == false)
{
this.txtbxDepaName.CausesValidation = true;
}
} this.txtbxDepaName.CausesValidation = aMsg .Msg != WM_CLOSE;
参考如下代码:
using System.Runtime.InteropServices;[DllImport("user32.dll")]
public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
public const uint GW_CHILD = 5;public class SubWindow : NativeWindow
{
protected override void WndProc(ref Message m)
{
const int WM_CONTEXTMENU = 0x007B;
switch (m.Msg)
{
case WM_CONTEXTMENU: return;
}
base.WndProc(ref m);
}
}private void Form1_Load(object sender, EventArgs e)
{
SubWindow vSubWindow = new SubWindow();
vSubWindow.AssignHandle(GetWindow(comboBox1.Handle, GW_CHILD));
}