假设我有下一个布局:
Window
UserControl
UserControl
UserControl
Button
GridControl
GridCell
假设 GridCell 当前具有键盘焦点。如果用户单击按钮。将向用户显示一条消息以确认操作。无论用户选择什么选项(是或否),焦点都应返回到 GridControl 上的 CurrentCell。默认情况下,用户选择某个选项后,焦点将返回到窗口(Snoop 报告)。我假设单击的按钮会保留焦点,但显然不会。
按钮命令的处理在 ViewModel (MVVM) 中完成。
如何将键盘焦点返回到网格中的当前单元格?
您可以通过在按钮上设置
FocusManager.IsFocusScope="true"
或如果有多个按钮及其所在的父元素(例如 StackPanel
或其他)来非常安全地解决此问题。
如果您使用
RoutedCommands
,则会出现一些潜在问题。基本上,RoutedCommands
并不总是按照您期望的方式在焦点范围内工作。听起来您正在直接绑定到视图模型上的命令,所以这应该不是问题。如果您想了解有关 RoutedCommand
问题的更多信息,请查看 此代码项目文章。
这是我验证此功能的示例代码,供您参考。
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="25">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--You could also have the FocusManager.IsFocusScope set on the Border instead-->
<Border Margin="0,0,0,15">
<Button FocusManager.IsFocusScope="True" Click="ButtonBase_OnClick">Click me!</Button>
</Border>
<TextBox Grid.Row="1" x:Name="MessageTextBox"></TextBox>
</Grid>
</Window>
C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Clicked, message: " + MessageTextBox.Text);
}
}
对我来说,问题实际上是焦点瞄准镜本身。当按下按钮时(通过鼠标或键盘 - 无关紧要),它将焦点重置到第一个文本框。
从 StackPanel 中删除 Focus Scope 时,按钮在按下时不再失去焦点。
<StackPanel><!--FocusManager.IsFocusScope="True">-->
<TextBox />
<TextBox />
<TextBox />
<Button>Click me!</Button>
<TextBox />
<TextBox />
<TextBox />
</StackPanel>