防止焦点在飞出时切换到主窗体 IsOpen=false;

Prevent focus switch to main form on fly out IsOpen=false;

我有一个 MetroWindow。它有一个弹出窗口。 Flyout 有一个按钮。按下 Flyout 按钮时,将显示一个新的 MetroWindow 并关闭该弹出按钮。

发生的是:

  1. 用户按下弹出按钮。
  2. 按下按钮打开一个新的非模态窗体并将 Flyout 的 IsOpen 设置为 false。
  3. 非模态形式在所有内容之上打开。
  4. 弹出窗口关闭。
  5. 弹出窗口关闭后主窗体获得焦点 - 隐藏非模态窗体。

我不希望在弹出窗口关闭时将焦点更改到主窗体。

我有一个可行的方法,但它有点滞后,因为它必须等待弹出动画完成。

有没有更好的方法?我不想让新的 window 成为模态或 AlwaysOnTop。

    private void SearchResultClose(object sender, RoutedEventArgs e)
    {
        m_EvtResultClosed.Set();
    }

    private void SearchResultOpenChange(object sender, RoutedEventArgs e)
    {
        if (foSearchResult.IsOpen)
        {
            m_EvtResultClosed.Reset();
        }
    }

<controls:Flyout Position="Top" Header="" x:Name="foSearchResult"
 Height="275" ClosingFinished="SearchResultClose" IsOpenChanged="SearchResultOpenChange">

    private void OpenPersonCard(object sender, RoutedEventArgs e)
    {
        var selected_person = SearchPersonResultsVM.View.CurrentItem as Editable<Person>;

        if (selected_person != null)
        {
            var card = new PersonFileWindow();
            card.Person = selected_person;
            foSearchResult.IsOpen = false;

            // Wait for it to close, and then show the form.
            Dispatcher.BeginInvoke(new Action(async () =>
            {
                await Task.Run(() =>
                {
                    m_EvtResultClosed.WaitOne();
                });
                card.Show();
            }), null);

        }
    }

哪里

 private AutoResetEvent m_EvtResultClosed = new AutoResetEvent(false);

查看 MahApps 的 Flyout.cs 中的函数 IsOpenedChanged,我们看到它在关闭时调用 Focus(),无论其是否为动画。也是评论:

 // focus the Flyout itself to avoid nasty FocusVisual painting (it's visible until the Flyout is closed)

但我不知道它到底想解决什么。

https://github.com/MahApps/MahApps.Metro/blob/1.2.4/MahApps.Metro/Controls/Flyout.cs

最简单的技巧是将 Focusable="False" 添加到您的弹出按钮中:

<controls:Flyout Focusable="False" Position="Top" Header="" x:Name="foSearchResult"Height="275" ClosingFinished="SearchResultClose" IsOpenChanged="SearchResultOpenChange">

它在这里工作正常,我无法分辨源中评论的任何令人讨厌的 FocusVisual 绘画。

默认情况下,当打开时,Flyout 会为自己窃取焦点,或者如果 Focusable==false,对于其中的某些控件,甚至是关闭按钮。在任何情况下,焦点都不会恢复到前一个元素。

所以,仅仅设置Focusable="False"可能无法解决问题。

相反,Flyout 提供 AllowFocusElement 属性 来抑制此行为:

<controls:Flyout AllowFocusElement="False" ... >