背景:
UI中有一个TabControl, 包含2个TabItem,当切换到别的TabItem时可能弹框然后根据逻辑判断是否跳转过去。
然后我就做了这样一个demo:
xaml:
<
UserControl
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns
:
x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns
:
d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns
:
mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns
:
i
="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns
:
ic
="http://schemas.microsoft.com/expression/2010/interactions"
xmlns
:
local
="clr-namespace:WpfApplication4"
mc
:
Ignorable
="d"
x
:
Class
="WpfApplication4.MainView"
d
:
DesignWidth
="640"
d
:
DesignHeight
="480" >
<
Grid
x
:
Name
="LayoutRoot" >
<
TabControl
x
:
Name
="tbcTest"
SelectionChanged
="TabControl_SelectionChanged" >
<
TabItem
x
:
Name
="tiItem1"
Header
="TabItem1" >
<
Grid
Background
="#FFE5E5E5" >
<
Button
Content
="Button"
VerticalAlignment
="Top"
Margin
="73,197,142,0" />
</
Grid
>
</
TabItem
>
<
TabItem
x
:
Name
="tiItem2"
Header
="TabItem2"
PreviewMouseLeftButtonDown
="TabItem_PreviewMouseLeftButtonDown" >
<
Grid
Background
="#FFE5E5E5" >
<
RadioButton
Content
="RadioButton"
HorizontalAlignment
="Left"
VerticalAlignment
="Top" />
</
Grid
>
</
TabItem
>
</
TabControl
>
</
Grid
>
</
UserControl
>
C# code:
using
System
.
Windows
;
using
System
.
Windows
.
Controls
;
namespace
WpfApplication4
{
public
partial
class
MainView
:
UserControl
{
public
MainView
()
{
// Required to initialize variables
InitializeComponent
();
}
private
void
TabControl_SelectionChanged
(
object
sender
,
System
.
Windows
.
Controls
.
SelectionChangedEventArgs
e
)
{
System
.
Diagnostics
.
Debug
.
WriteLine
(
"SelectionChanged..."
);
}
private
void
TabItem_PreviewMouseLeftButtonDown
(
object
sender
,
System
.
Windows
.
Input
.
MouseButtonEventArgs
e
)
{
System
.
Diagnostics
.
Debug
.
WriteLine
(
"PreviewMouseLeftButtonDown"
);
MessageBox
.
Show
(
"Test Modal Window"
);
}
}
}
问题来了:
当点击第2个tabItem弹框后,tabControl并没有切换过去。
原因:
通过snoop的event分析后, 发现区别在于当弹框后焦点在Window上而不是TabItem上。
(1)没有弹messagebox的事件
(2)弹messagebox后的事件
解决办法:
很简单,不需要指定TabControl的SelectedItem, 不需要RaiseEvent。只需在MessageBox之后调用Focus()。
private
void
TabItem_PreviewMouseLeftButtonDown
(
object
sender
,
System
.
Windows
.
Input
.
MouseButtonEventArgs
e
)
{
System
.
Diagnostics
.
Debug
.
WriteLine
(
"PreviewMouseLeftButtonDown"
);
if
(
_isPopupMsgBox
)
{
MessageBox
.
Show
(
"Test Modal Window"
);
}
if
(
_isPopupMsgBox
)
{
var
tabItem
=
sender
as
TabItem
;
if
(
tabItem
!=
null
)
{
//当在当前的界面上弹出二级界面再次关闭后,
//焦点默认在当前窗体上,导致后续MouseDown事件并没有在TabItem上生效。
tabItem.Focus();
}
}
}