单击时,WPF Popup不会导致应用程序被聚焦

时间:2012-04-24 01:16:24

标签: wpf popup

我有一个控件正在使用弹出窗口,里面有一些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>
  1. 运行该应用程序。
  2. 与列表框进行交互,这应该可以正常工作。
  3. 切换到另一个应用程序。
  4. 在应用程序未处于活动状态时单击列表框。什么都没发生
  5. 点击列表框外的应用程序。
  6. 点击列表框。它现在正在运作。
  7. 我期望在第4步中发生的是应用程序将获得焦点,列表框将选择新项目。

    这个问题是否有任何变通方法,或者我忽略了一些明显的问题?我正在考虑用完整的窗口重写整个弹出代码,并重新实现我们的行为,但这似乎很复杂只是为了解决这样的小问题。

2 个答案:

答案 0 :(得分:6)

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

你可以遇到的问题是在Windows上你可以交换鼠标按钮,左边是正确的,反之亦然(但我不知道它是如何工作的),所以,你可能需要处理{{1}事件。

答案 1 :(得分:0)

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

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

C#:

/// <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();
}