如何以编程方式将键盘焦点放在 WPF TreeViewItem 上?
我正在尝试以编程方式将键盘焦点设置为树视图项(在某些条件下)。我尝试了两种设置焦点的方法,这两种方法都成功获得了 TreeViewItem
上的焦点,但失去了键盘焦点。
树视图绑定到视图模型:
<TreeView Name="solutionsModel" TreeViewItem.Selected="solutionsModel_Selected"
ItemsSource="{Binding Items, Mode=OneWay}" />
我试图通过 TreeViewItem
Selected
路由事件设置焦点:
private void solutionsModel_Selected(object sender, RoutedEventArgs e)
{
if (solutionsModel.SelectedItem != null && solutionsModel.SelectedItem is SolutionViewModel)
{
if (e.OriginalSource != null && e.OriginalSource is TreeViewItem)
{
FocusManager.SetFocusedElement(solutionsModel, e.OriginalSource as TreeViewItem);
}
}
}
我试图将焦点设置在
:ControlTemplate
中的 TreeViewItem
<Style d:IsControlPart="True" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Trigger.Setters>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"></Setter>
</Trigger.Setters>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<!--
<MultiTrigger.Setters>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"></Setter>
</MultiTrigger.Setters>
-->
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这两种方法都获得焦点,但失去键盘焦点(TreeViewItem.IsSelectionActive
为 false)。我可以告诉窗口中的其他元素没有焦点或键盘焦点(在测试中,我在另一个面板上只有一个可以获得焦点的只读文本框)。有趣的是,我可以将键盘焦点放在(注释掉的)MultiTrigger
上,其中 IsSelectionActive
为 false,但这当然会强制键盘焦点放在 TreeViewItem
上随时。
是否有其他方法可以更好地获得键盘焦点,以及哪些情况无法获得键盘焦点?
I'm trying to programatically set keyboard focus to a tree view item (under certain conditions). I've tried 2 methods of setting focus, both of which successfully obtain focus on the TreeViewItem
, but lose keyboard focus.
The tree view is bound to a view model:
<TreeView Name="solutionsModel" TreeViewItem.Selected="solutionsModel_Selected"
ItemsSource="{Binding Items, Mode=OneWay}" />
I'm trying to set focus via the TreeViewItem
Selected
routed event:
private void solutionsModel_Selected(object sender, RoutedEventArgs e)
{
if (solutionsModel.SelectedItem != null && solutionsModel.SelectedItem is SolutionViewModel)
{
if (e.OriginalSource != null && e.OriginalSource is TreeViewItem)
{
FocusManager.SetFocusedElement(solutionsModel, e.OriginalSource as TreeViewItem);
}
}
}
I'm trying to set focus on the TreeViewItem
in the ControlTemplate
:
<Style d:IsControlPart="True" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Trigger.Setters>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"></Setter>
</Trigger.Setters>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<!--
<MultiTrigger.Setters>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"></Setter>
</MultiTrigger.Setters>
-->
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Both of these methods get focus, but lose keyboard focus (TreeViewItem.IsSelectionActive
is false). No other element in the window has focus or keyboard focus that I can tell (in a test, I only have one read only textbox on another panel that could get focus). Interestingly, I can get keyboard focus on the (commented out) MultiTrigger
where IsSelectionActive
is false, but of course that forces keyboard focus on the TreeViewItem
at all times.
Is there another way to have a better chance of getting keyboard focus, and what are some conditions where keyboard focus cannot be obtained?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果可以的话,我会将其添加为注释,但是为什么不让
TreeView
处理焦点并使用TreeView.SelectedItem
抽象地处理该项目。树视图始终能够知道在输入开始时选择了哪个项目。如果选择了某个项目,则TreeView
处于焦点状态,您可以通过管道将键盘命令传递给该项目。I'd add this as a comment if I could but, why not just have the
TreeView
handle the focus and work with the item abstractly using theTreeView.SelectedItem
. The tree view would always be able to know which item was selected when the typing started. If an item was selected then theTreeView
is in focus and you can pipe the keyboard commands through to the item.可能有更好的方法,但我找到了一种通过扩展 TreeView 和 TreeViewItem 来实现此目的的方法,以在以下情况下触发单独的 NeedsFocus 属性:设定焦点。
树视图:
更新的(部分)控件模板:
扩展类:
在视图模型中,每当设置
IsSelected
时,NeedsFocus
都会设置为 false。There are probably better ways, but I found a way to do this by extending
TreeView
andTreeViewItem
, to have a separateNeedsFocus
property to trigger when to set focus.The tree view:
The updated (partial) control template:
The extended classes:
In the view model,
NeedsFocus
is set to false wheneverIsSelected
is set.