[英]How can I programatically get keyboard focus on a 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
是假的,但當然,這迫使鍵盤注重的TreeViewItem
在任何時候。
是否有另一種方法可以更好地獲得鍵盤焦點,以及無法獲得鍵盤焦點的條件是什么?
如果可以的話,我會將其添加為注釋,但為什么不讓TreeView
處理焦點並使用TreeView.SelectedItem
抽象地處理項目。 樹視圖始終能夠知道在鍵入開始時選擇了哪個項目。 如果選擇了某個項目,則TreeView
將處於焦點,您可以將鍵盤命令傳遞給該項目。
可能有更好的方法,但我找到了一種方法,通過擴展TreeView
和TreeViewItem
來實現這一點,以便有一個單獨的NeedsFocus
屬性來觸發何時設置焦點。
樹視圖:
<local:ModelTreeView x:Name="solutionsModel" ItemsSource="{Binding Items, Mode=OneWay}">
</local:ModelTreeView>
更新的(部分)控件模板:
<Style d:IsControlPart="True" TargetType="{x:Type local:ModelTreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="NeedsFocus" Value="{Binding NeedsFocus, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ModelTreeViewItem}">
<ControlTemplate.Triggers>
<Trigger Property="NeedsFocus" Value="true">
<Trigger.Setters>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"></Setter>
</Trigger.Setters>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
擴展類:
public class ModelTreeView : TreeView
{
protected override DependencyObject GetContainerForItemOverride()
{
return new ModelTreeViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is ModelTreeViewItem;
}
}
public class ModelTreeViewItem : TreeViewItem
{
///--------------------------------------------------------------------------------
/// <summary>This property gets or sets whether the item needs focus.</summary>
///--------------------------------------------------------------------------------
public static readonly DependencyProperty NeedsFocusProperty = DependencyProperty.Register("NeedsFocus", typeof(bool), typeof(ModelTreeViewItem));
public bool NeedsFocus
{
get
{
return (bool)GetValue(NeedsFocusProperty);
}
set
{
SetValue(NeedsFocusProperty, value);
}
}
protected override DependencyObject GetContainerForItemOverride()
{
return new ModelTreeViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is ModelTreeViewItem;
}
}
在視圖模型中, NeedsFocus
設置了IsSelected
, NeedsFocus
就會設置為false。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.