防止焦点在飞出时切换到主窗体 IsOpen=false;
Prevent focus switch to main form on fly out IsOpen=false;
我有一个 MetroWindow。它有一个弹出窗口。 Flyout 有一个按钮。按下 Flyout 按钮时,将显示一个新的 MetroWindow 并关闭该弹出按钮。
发生的是:
- 用户按下弹出按钮。
- 按下按钮打开一个新的非模态窗体并将 Flyout 的 IsOpen 设置为 false。
- 非模态形式在所有内容之上打开。
- 弹出窗口关闭。
- 弹出窗口关闭后主窗体获得焦点 - 隐藏非模态窗体。
我不希望在弹出窗口关闭时将焦点更改到主窗体。
我有一个可行的方法,但它有点滞后,因为它必须等待弹出动画完成。
有没有更好的方法?我不想让新的 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" ... >
我有一个 MetroWindow。它有一个弹出窗口。 Flyout 有一个按钮。按下 Flyout 按钮时,将显示一个新的 MetroWindow 并关闭该弹出按钮。
发生的是:
- 用户按下弹出按钮。
- 按下按钮打开一个新的非模态窗体并将 Flyout 的 IsOpen 设置为 false。
- 非模态形式在所有内容之上打开。
- 弹出窗口关闭。
- 弹出窗口关闭后主窗体获得焦点 - 隐藏非模态窗体。
我不希望在弹出窗口关闭时将焦点更改到主窗体。
我有一个可行的方法,但它有点滞后,因为它必须等待弹出动画完成。
有没有更好的方法?我不想让新的 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" ... >