WPF弹出窗口在单击时不会导致应用程序聚焦

WPF弹出窗口在单击时不会导致应用程序聚焦,wpf,popup,Wpf,Popup,我有一个控件正在使用一个带有一些WPF控件的弹出窗口,并且StaysOpen=“True”。问题是,当应用程序没有焦点时,单击弹出窗口时,应用程序没有收到焦点。我做了一些研究,似乎这可能是因为弹出窗口用于菜单,所以它们没有连接所有正确的windows消息处理程序。下面是演示问题的简单示例: <Window x:Class="TestWindowPopupBehavior.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20

我有一个控件正在使用一个带有一些WPF控件的弹出窗口,并且StaysOpen=“True”。问题是,当应用程序没有焦点时,单击弹出窗口时,应用程序没有收到焦点。我做了一些研究,似乎这可能是因为弹出窗口用于菜单,所以它们没有连接所有正确的windows消息处理程序。下面是演示问题的简单示例:

<Window x:Class="TestWindowPopupBehavior.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:TestWindowPopupBehavior="clr-namespace:TestWindowPopupBehavior" Title="MainWindow" Height="350" Width="525">
<Grid>
    <Popup StaysOpen="True" IsOpen="True" Placement="Center">
        <ListBox>
            <TextBlock>123</TextBlock>
            <TextBlock>123</TextBlock>
            <TextBlock>123</TextBlock>
            <TextBlock>123</TextBlock>
            <TextBlock>123</TextBlock>
            <TextBlock>123</TextBlock>
        </ListBox>
    </Popup>

</Grid>
</Window>

123
123
123
123
123
123
  • 运行应用程序
  • 与listbox交互,它应该可以正常工作
  • 切换到另一个应用程序
  • 当应用程序处于非活动状态时,单击列表框。什么也没发生
  • 单击列表框外的应用程序
  • 单击列表框。它现在正在工作
  • 我希望在第4步中,应用程序将获得焦点,列表框将选择新项目


    这个问题有没有解决办法,或者我明显遗漏了什么?我正在考虑用成熟的窗口重写整个弹出代码,并重新实现我们的行为,但仅仅解决这样一个小问题就显得非常复杂。

    如果处理
    MouseLeftButtonDown
    事件,可以调用
    Window.Activate()
    方法。但是您应该为每个元素-
    Popup
    和所有
    TextBlock
    s编写它


    您可能遇到的问题是,在Windows上,您可以交换鼠标按钮,左键变成右键,反之亦然(但我不知道这是如何工作的),因此,您可能必须处理
    MouseRightButtonDown
    事件。

    今天我自己遇到了这个问题

    如果需要,可以通过在app.xaml.cs中的弹出类本身上注册类处理程序来全局修复它:

    C#:

    //
    启动时受保护的覆盖无效(StartupEventArgs e)
    {
    RegisterClassHandler(typeof(Popup)、UIElement.PreviewMouseDownEvent、newRoutedEventHandler(Popup_PreviewMouseDownEvent));
    }
    /// 
    ///确保在弹出窗口上调用之前激活应用程序。
    ///这解决了一个问题,即如果您将注意力集中在另一个应用程序上,并在弹出窗口中单击“返回”,弹出窗口似乎被冻结。
    /// 
    /// 
    /// 
    私有无效弹出窗口\u预览MousedownEvent(对象,路由目标)
    {
    当前?.main窗口?.Activate();
    }
    
    使用预览就足够了。。。鼠标事件将其捕获在弹出窗口中,而无需为其内容添加更多处理程序。你们能更具体地了解预览内容吗?我似乎也遇到了同样的问题。@AlexMcManns将PreviewMouseLeftButtonDown和/或PreviewMouseRightButtonDown事件的处理程序添加到弹出窗口本身。在这些处理程序中,调用(例如)Application.Current.MainWindow.Activate()。弹出窗口的子控件不需要处理程序。
    /// <inheritdoc />
    protected override void OnStartup(StartupEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(Popup), UIElement.PreviewMouseDownEvent, new RoutedEventHandler(Popup_PreviewMouseDownEvent));
    }
    
    /// <summary>
    /// Ensures that the application is activated before the <see cref="UIElement.MouseDownEvent"/> is invoked on the Popup.
    /// This solves an issue where the Popup seemed to be frozen if you focused out to another application and clicked back in the Popup itself.
    /// </summary>
    /// <param name="_"></param>
    /// <param name="__"></param>
    private void Popup_PreviewMouseDownEvent(object _, RoutedEventArgs __)
    {
        Current?.MainWindow?.Activate();
    }