我有一个TabControl与多个tabpage,每个tabpage包含多个控件。当用户使用按钮离开我的选项卡时,我想验证该选项卡上的控件是否被正确修改。具体来说,我想检查他们是否选择了一个单选按钮。
发生的是,如果验证失败(意思是,我设置CancelEventArgs为true), UI不再响应输入。控件仍然响应悬停和单击(意思是,颜色改变),但不采取任何操作。我无法导航到其他选项卡,甚至无法使用"X"按钮关闭应用程序。
我试过添加errorProvider,添加SelectTab调用,添加Focus()调用到选项卡和选项卡上的控件,并添加MessageBox。MessageBox允许我点击OK,但随后返回到"锁定"的UI。将Focus()调用添加到当前选项卡上的控件(验证失败)会导致选择下一个控件,但UI仍然被锁定。
知道为什么会发生这种情况或者如何绕过它吗?
注意:只有当我尝试使用选项卡上的按钮更改选项卡时才会发生这种情况。如果我只是点击另一个选项卡,取消工作,我被拉回到我的选项卡与所有可用的控件。
编辑:我终于有时间重新审视这个问题了。我创建了一个简单的2选项卡控件,其中包含取消验证的复选框。为了演示"锁定"功能,我在选项卡上添加了一些其他控件(单选按钮和文本框),但这里没有包括它们,因为它们背后没有代码。这段代码说明了我遇到的问题。选中复选框并单击button1后,所有控件都变得无响应。代码如下。项目文件可按要求提供。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TabEventTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex++;
}
private void button2_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex--;
}
private void tabPage2_Validating(object sender, CancelEventArgs e)
{
if (checkBox2.Checked)
{
e.Cancel = true;
}
}
private void tabPage1_Validating(object sender, CancelEventArgs e)
{
if (checkBox1.Checked)
{
e.Cancel = true;
}
}
}
}
经过大量研究,我得出的结论是,这不能使用在TabPage级别引发的事件来完成。我在2006年的MSDN论坛上发现了一个和我的问题类似的帖子,结论是这是。net框架中的一个bug。如果这是真的,在我看来,它还没有修好。
我完成验证的方式是使用TabControl上的取消选择事件。这意味着我对所有选项卡都有一个事件处理程序(然后我有基于被取消选中的选项卡而触发的自定义验证函数),这并不像我希望的那样干净,但它是功能性的。我不能像之前建议的那样使用选择事件,因为它只给了我要导航到的标签,我需要验证我要离开的标签。我错过了第一次取消选择的存在。
事件处理程序中的代码:
private void tabControl1_Deselecting(object sender, TabControlCancelEventArgs e)
{
switch (e.TabPageIndex)
{
case 0:
if (!validateTab1())
{
e.Cancel = true;
}
break;
case 1:
if (!validateTab2())
{
e.Cancel = true;
}
break;
default:
break;
}
}
看起来您错误地使用了验证处理程序。你应该使用CancelEventArgs参数来取消导航,而不是强迫选项卡控件转到或停留在选项卡上。
查看这篇MSDN文章,了解有关CancelEventArgs的文档。取消属性和这个Q/A线程,为您的特定场景提供解释和代码示例。
你也可以使用选项卡控件的选择事件来执行验证并阻止选项卡页面的更改。
选择事件发生在选项卡被选中之前取消制表符更改的处理程序。
在这种情况下,您将使用TabControlCancelEventArgs
参数来设置Cancel = true;