我有一个控件正在使用弹出窗口,里面有一些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>
我期望在第4步中发生的是应用程序将获得焦点,列表框将选择新项目。
这个问题是否有任何变通方法,或者我忽略了一些明显的问题?我正在考虑用完整的窗口重写整个弹出代码,并重新实现我们的行为,但这似乎很复杂只是为了解决这样的小问题。
答案 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();
}