c# 触发控件textBox1_Validating 的窗体关闭问题

form1 中有控件textBox1, 为其设置事件textBox1_Validating
窗体在showDialog()下, 此事件验证不通过时,为何还响应窗体Close事件退出窗体。
而在show()下,是不响应任何事件。
大家试试,怎么回事呀?
我准备为DataTable建立一个通用的浏览、编辑(增删改)的窗体,
根据不同的DataColumn动态建立TextBox, CheckBox, NumericBox等并与其绑定,
来显示DataRow数据。

问题:在新增一行或修改DataRow时,用户必须为非Null(或其它验证规则,这个校验规则是没错的)项输入数据,

否则触发 Validating 事件, e.Cancel = true, 焦点一直停留在此控件,禁止保存,也禁止用户关闭窗体。

这个窗体必须用ShowDialog()来模态显示,触发 Validating 事件时,也就是说用户录入的数据是错误的或未录入数据,

要禁止用户关闭窗体。而恰恰相反,可以关闭。而窗体用Show()时,是不可以关闭窗体的

但这不是我想要的,窗体必须是模态的。

不明白为何在模态下会响应关闭事件。

另:我不想在FormClosing中来判断,不是不可以,是比较繁琐。

窗体Close事件和textBox1的Validating验证之间没什么联系。

要想不关闭窗体,需要在窗体的FormClosing事件中增加e.Cancel=true;即可。追问

form1.Show()下,事件textBox1_Validating验证不通过,即e.Cancel = true时,
点击关闭窗口是无效的。

form1.ShowDialog()下,textBox1_Validating 中e.Cancel = true时,点击关闭窗口是可以关闭的。
我想要的是,在ShowDialog()模态窗口下,textBox1_Validating验证不通过时,禁止用户关闭窗体。

而不是去设置formClosing中e.Cancel。

追答

Form 的Show和ShowDialog的主要区别就在于句柄,常理上讲,应该不至于影响到你的textBox1_Validating 。你可以再查查实现逻辑。

另外,你说的“禁止用户关闭窗体。”是什么意思?是需要窗体的关闭按钮就不可用是吗?

追问

// 只创建textBox1, button1, errorProvider1
private void textBox1_Validating(object sender, CancelEventArgs e)
{
e.Cancel = textBox1.Text == "error";
errorProvider1.SetError(textBox1, e.Cancel ? "错误" : "");
}

private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("响应Button.");
}

追答

是这样的。你所说的e.Cancel 和我说的e.Cancel 不是一个意思。
你定义一个类级变量,private bool chkResult=true;
在textBox1_Validating中验证不通过,怎将chkResult设置为false

在FormClosing这个事件中!!!!判断如果chkResult为false,则e.Cancel =true;

追问

你看一下我的问题补充。谢谢。
主要是不明白,为何模态下会响应关闭事件,而非模态下不会。

追答

你描述的这个问题有点特殊,你可以试试直接调用Windows的API来控制窗体不能关闭。
大致的实现如下:
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_MOVE = 0xF010;
private const int HTCAPTION = 0x0002;
private const int WS_SYSMENU = 0x00080000; //系统菜单
private const int WS_MINIMIZEBOX = 0x20000; //最大最小化按钮
private const int SC_RESIZEALL = 0xF008; //拖动调整长宽大小
private const int SC_RESIZEWIDTH = 0xF002; //拖动调整宽度
private const int SC_RESIZEHEIGHT = 0xF006; //拖动调整高度
[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
private static extern IntPtr SetWindowLong(HandleRef hWnd, int nIndex, int dwNewLong);

在需要设置窗体特殊效果的地方增加如下两句:
int windowLong = (GetWindowLong(new HandleRef(this, this.Handle), -16));
SetWindowLong(new HandleRef(this, this.Handle), -16, ^windowLong ^WS_SYSMENU ^WS_MINIMIZEBOX);
试试看行不行

追问

帮我看下,是不是业务逻辑有问题呀?

追答

你把完整代码贴出来,我帮你看看吧!

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-04-11
e.Cancel
相似回答