一旦从TabControl上的SelectedIndexChanged事件抛出异常,就无法以编程方式更改选项卡页面

时间:2009-09-22 07:42:15

标签: winforms c#-3.0 tabcontrol

这是一个C#,Winform问题。

我有一个TabControl控件,我使用两个导航按钮在我的标签页之间切换。我使用TabControl.SelectedIndex = i来更改按钮的单击事件中的显示选项卡页面。每次要显示特定标签页时,都会调用其中一个函数来准备一些后台工作。对函数的调用将放在TabControl.SelectedIndexChanged事件中。

我遇到了一个问题。如果从TabControl.SelectedIndexChanged事件抛出异常(从该事件中调用的几个函数之一),我不再可以使用编程方式在标签页之间切换。抛出一个异常后,导航按钮无法更改TabControl的显示选项卡。更具体地说,TabControl的SelectedIndex仍然可以更改,标签页UI仍然会更改,但标签页内容仍然与异常抛出的页面相同。

之前有人遇到过这个问题吗?有解决方案吗非常感谢。

1 个答案:

答案 0 :(得分:2)

作为一般规则,应捕获并处理WinForms事件处理程序中的异常。如果允许异常将堆栈上传到WinForms代码中,那么奇怪的行为 - 就像你遇到的那样 - 是一种常见的结果。

使用Reflector查看System.Windows.Forms.TabControl,其WndProc()方法调用WmSelChange(),它调用您的事件处理程序。当事件处理程序中发生异常时,异常会将堆栈渗透到WndProc。 WndProc不处理异常,因此WndProc末尾的if / then语句永远不会被调用:

if (m.Msg == this.tabBaseReLayoutMessage)
{
    this.WmTabBaseReLayout(ref m);
}
else
{
    base.WndProc(ref m);
}

因此,选项卡控件的内部状态已损坏,导致奇怪的行为。

为了干净地处理在选项卡更改期间可能发生的异常,我建议使用Selecting事件来执行后台工作(此事件在SelectedIndexChanged事件之前被触发)。使用try / catch语句,并在catch子句中将TabControlCancelEventArgs.Cancel设置为true以取消选项卡更改。