Kev*_*ski 6 wpf keyboard-shortcuts
问题:按下并释放Alt键后,如何退出键盘热键模式?在Office中的ESC作品,在WPF中它没有.
详细信息:我Label在WPF应用程序中有各种元素.
<StackPanel>
<Label Grid.Column="0" VerticalAlignment="Center" Content="_Textbox 1" Target="textbox1" />
<TextBox x:Name="textbox1" Width="50" />
<Label Grid.Column="0" VerticalAlignment="Center" Content="T_extbox 2" Target="textbox2" />
<TextBox x:Name="textbox2" Width="50" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
当我按下并释放Alt键时,P保持下划线,然后我可以单独按下P键,Label就会采取行动.这与Word 2013和Notepad的工作方式相同,因为您无需同时按Alt和P.
WPF不同的地方是我不能ESC按键来停止下划线并停止自动导航到Label控件.我看到退出键盘导航模式的唯一方法是使用鼠标并单击某处,从而击败键盘导航的目标.
添加到我原来的评论
实际上,记事本和 Word 2013 的行为略有不同。带有热键的控件位于菜单中,一旦您按 Alt,您就会获得焦点,您可以看到它们获得焦点,因为文本区域插入符号丢失,然后 Esc 将焦点返回到文本框,同时清除“_”。现在,在示例代码中,如果将两个标签或什至一个标签放入 a 中,然后按 Alt,您将获得与 Word 或记事本相同的行为。如果没有菜单,就没有控件想要获得中间焦点。
这似乎是一个问题,在它自己的FocusManager.IsFocusScopeMenu中获得延迟焦点来处理这些热键。
MSDN的另一个片段:
以下方案说明了 Windows Presentation Foundation (WPF) 应用程序中键盘焦点和逻辑焦点如何更改,该应用程序具有带 TextBox 的 Window 和带 MenuItem 的 Menu。当键盘焦点从 TextBox 更改为 MenuItem 时,TextBox 会失去键盘焦点,但会保留 Window 焦点范围的逻辑焦点。MenuItem 获取键盘焦点并获取 Menu 焦点范围的逻辑焦点。当键盘焦点返回到根Window时,Window焦点范围内具有逻辑焦点的元素将获得键盘焦点,在本例中为TextBox。TextBox 现在具有键盘焦点和逻辑焦点。MenuItem 失去键盘焦点,但保留菜单焦点范围的逻辑焦点。
解决方案:
Menu如果您无法忍受实现热键功能所施加的分组要求的限制,您可以执行以下操作:
<Grid Margin="25">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="15" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- cannot use Visibility="Collapsed" or "Hidden" on the Menu to make it take focus on Alt press -->
<Menu Width="0"
Height="0">
<Label x:Name="label1"
Content="_Textbox 1"
Target="{Binding ElementName=textbox1}" />
<Label x:Name="label2"
Content="T_extbox 2"
Target="{Binding ElementName=textbox2}" />
<Label x:Name="label3"
Content="Another Loose Label to Link Text_Box 1"
Target="{Binding ElementName=textbox1}" />
</Menu>
<Label Grid.Row="0"
Grid.Column="0"
Content="{Binding ElementName=label1,
Path=Content}" />
<TextBox x:Name="textbox1"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="15 0 0 0"
VerticalAlignment="Center" />
<Label Grid.Row="2"
Grid.Column="0"
Content="{Binding ElementName=label2,
Path=Content}" />
<TextBox x:Name="textbox2"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="15 0 0 0"
VerticalAlignment="Center" />
<Rectangle Grid.Row="3"
Grid.RowSpan="2"
Grid.Column="1"
Margin="10"
Fill="Tomato" />
<Label Grid.Row="4"
Grid.Column="2"
Content="{Binding ElementName=label3,
Path=Content}" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
因此,在此设置中,我们不Style为任何控件使用任何自定义。我们几乎创建了一个新的顶层Menu,并向其中添加所有所需的热键Label,并将其宽度和高度设置为 0。
因此,在实际的可见Grid布局中,我们可以将可见的位置放置Label在我们选择的任何位置,并且为了避免Label.Content为每个指定两次Label(在菜单中一次,在实际布局中的下一个)时重复代码,我们使用绑定来获取视觉标签的内容从菜单中相应的标签。
更新
回复OP的评论:
我不确定这在我的应用程序中是否实用。我的应用程序中到处都有热键,其中一些热键在屏幕间是重复的。实施这种类型的解决方法是不可维护的。
好吧,我不明白重复或到处都是东西对这个问题有什么影响。
Window如果您在多个'中有重复的热键,则将Content这些重复的项目定义为Stringxaml 或 .resx 中的资源,您可以在任何需要的地方引用它。<Menu>顶层,并且在该窗口中任何需要该功能的控件都绑定到相应的菜单子项。我认为它将热键的范围统一到一个地方,而不是多个不同地方。WindowWindowWindow最后,我并不是想把这种方法强加给你,这取决于你的个人喜好。如果您对此感到不舒服,那么您可以对您的Label进行子分类并自己实现延迟焦点的功能,或者提出 Microsoft 错误,看看他们是否可以为您解决该问题或找到替代解决方案或放弃热门-关键功能全部放在一起。
| 归档时间: |
|
| 查看次数: |
931 次 |
| 最近记录: |