WPF中PreviewMouseDownEvent的系统处理:TabItem的PreviewMouseDown 事件弹框后不切换的问题调查

来源:互联网 发布:旅行哲学知乎 编辑:程序博客网 时间:2024/05/16 08:48

背景:
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();
                }
            }
        }
1 0
原创粉丝点击