3

我正在尝试以编程方式将键盘焦点设置为树视图项(在某些条件下)。我尝试了两种设置焦点的方法,这两种方法都成功地获得了焦点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);
        }
    }
}

我正在尝试将重点TreeViewItem放在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>

这两种方法都获得焦点,但失去键盘焦点(TreeViewItem.IsSelectionActive为假)。窗口中没有其他元素具有我可以分辨的焦点或键盘焦点(在测试中,我在另一个面板上只有一个只读文本框可以获取焦点)。有趣的是,我可以将键盘焦点放在(注释掉的)错误的MultiTrigger地方IsSelectionActive,但当然这会强制键盘TreeViewItem始终关注。

是否有其他方法可以更好地获得键盘焦点,以及无法获得键盘焦点的情况有哪些?

4

2 回答 2

3

如果可以的话,我会将其添加为评论,但是,为什么不只是让TreeView手柄成为焦点并使用TreeView.SelectedItem. 树视图将始终能够知道在键入开始时选择了哪个项目。如果选择了某个项目,则该项目TreeView处于焦点位置,您可以将键盘命令通过管道传递给该项目。

于 2011-05-11T16:18:00.157 回答
2

可能有更好的方法,但我找到了一种方法,方法是扩展TreeViewand 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无论何时设置为 false IsSelected

于 2011-05-11T20:03:42.333 回答