TabControl 上的 SelectedIndexChanged 事件引发异常后,无法以编程方式更改选项卡页
这是一个C#、Winform问题。
我有一个 TabControl 控件,并使用两个导航按钮在选项卡页面之间切换。我使用 TabControl.SelectedIndex = i 更改按钮单击事件中显示的选项卡页。每次要显示特定选项卡页面时,都会调用几个函数之一来准备一些后台工作。对函数的调用被放入 TabControl.SelectedIndexChanged 事件中。
我遇到了一个问题。如果 TabControl.SelectedIndexChanged 事件(从该事件中调用的几个函数之一)引发异常,我将无法再使用编程方式在选项卡页面之间切换。一旦抛出异常,导航按钮就无法更改 TabControl 的显示选项卡。更具体地说,TabControl 的 SelectedIndex 仍然可以更改,选项卡 UI 仍然更改,但选项卡页面内容仍然与抛出异常的页面相同。
以前有人遇到过这个问题吗?有什么解决办法吗?非常感谢。
This is a C#, Winform question.
I have a TabControl control and I use two navigation buttons to switch among my tab pages. I used TabControl.SelectedIndex = i to change the showing tab pages in the buttons' click event. Every time a specific tab page is going to be shown, one of several functions is called to prepare some background work. The calls to the functions are put to TabControl.SelectedIndexChanged event.
I came across a problem. If an exception is thrown from TabControl.SelectedIndexChanged event (from one of the several functions get called in that event), I no longer can use the programmatic way to switch among tab pages. Once one exception is thrown, the navigation buttons cannot change the showing tab of the TabControl. Be more specifically, the SelectedIndex of TabControl still can be changed, the tabs UI still changes but the tab page content remains the same as the page that having exception thrown out.
Anyone came across this problem before? Any solution? Many thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
作为一般规则,应该捕获并处理 WinForms 事件处理程序中的异常。如果允许异常进入堆栈并进入 WinForms 代码,那么奇怪的行为(就像您所经历的那样)是常见的结果。
使用 Reflector 查看 System.Windows.Forms.TabControl,其 WndProc()方法调用 WmSelChange(),它调用您的事件处理程序。当事件处理程序中发生异常时,异常会向上渗透到堆栈中的 WndProc。 WndProc 不处理异常,因此 WndProc 末尾的 if/then 语句永远不会被调用:
因此选项卡控件的内部状态被破坏,导致奇怪的行为。
为了干净地处理选项卡更改期间可能发生的异常,我建议使用 Selecting 事件来执行后台工作(该事件在 SelectedIndexChanged 事件之前触发)。使用 try/catch 语句,并在 catch 子句中将 TabControlCancelEventArgs.Cancel 设置为 true 以取消选项卡更改。
As a general rule, exceptions in WinForms event handlers should be caught and handled. If the exception is allowed to go up the stack into the WinForms code, strange behavior - like what you're experiencing - is a common result.
Using Reflector to look at System.Windows.Forms.TabControl, its WndProc() method calls WmSelChange(), which calls your event handler. When an exception occurs in the event handler, the exception percolates up the stack to WndProc. WndProc doesn't handle the exception, so this if/then statement at the end of WndProc never gets called:
Therefore the tab control's internal state is corrupted, resulting in the odd behavior.
To cleanly handle exceptions that might occur during a tab change, I suggest using the Selecting event to perform the background work (this event gets fired before the SelectedIndexChanged event). Use a try/catch statement, and in the catch clause set TabControlCancelEventArgs.Cancel to true to cancel the tab change.