簡體   English   中英

如何以編程方式將鍵盤焦點放在WPF TreeViewItem上?

[英]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);
        }
    }
}

我正在嘗試將焦點放在ControlTemplateTreeViewItem上:

<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將處於焦點,您可以將鍵盤命令傳遞給該項目。

可能有更好的方法,但我找到了一種方法,通過擴展TreeViewTreeViewItem來實現這一點,以便有一個單獨的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設置了IsSelectedNeedsFocus就會設置為false。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM