WPF TreeView希望在选择父级时选择第一个子级

时间:2009-05-07 12:06:29

标签: wpf treeview treeviewitem

我正在使用演示模型在我的应用中使用TreeView控件实现导航。我通过双向绑定将TreeViewItem的IsSelected属性绑定到我的视图模型。当选择具有子节点的节点时,我希望选择该节点的第一个子节点而不是单击的节点。在我的演示模型上设置IsSelected属性时,似乎TreeViewItem不会侦听属性更改事件。选择了第一个子节点,但父节点未取消选择。这是我的演示模型中的代码。

public bool IsSelected {
    get {
        return this._isSelected;
    }
    set {
        if(this._isSelected != value) {
            this._isSelected = value;
            if(this.Nodes.Count > 0) {
                this._isSelected = false;
                this.Nodes[0].IsSelected = true;
            }
            this.NotifyPropertyChanged("IsSelected");
        }
    }
}

这是我TreeViewItem的风格:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>

3 个答案:

答案 0 :(得分:1)

我有一个非常相似的问题,我发现当我通过代码选择一个孩子时,我还需要将焦点放在TreeViewItem包装器上,这样父节点就会被称为“UnSelect”。所以在xaml中我添加了一个事件处理程序:

<EventSetter Event="TreeViewItem.Selected" 
                    Handler="TreeViewItem_Selected" 
                        />

在部分课程中:

Private Sub TreeViewItem_Selected(ByVal sender As System.Object, ByVal e As RoutedEventArgs)
            If CType(sender, TreeViewItem) IsNot Nothing Then
                CType(sender, TreeViewItem).Focus()
                e.Handled = True
            End If
End Sub

答案 1 :(得分:1)

另一种考虑的可能性:

TreeView尝试确保一次性选择树中的两个TreeViewItem,因此应该防止这种情况发生。也许这是TreeView中的一个错误,但它也可能是您使用TreeView的方式的一个问题。

为了效率,TreeView非常挑剔它如何找到它下面的TreeViewItems。该算法实际上是这种方式(以递增方式完成):

  1. 查看我的项容器中的TreeView对象
  2. 查看TreeView对象的项容器以查找更多TreeView对象
  3. 重复步骤3,直到找不到更多的TreeView对象
  4. 因此,如果TreeViewItems的每个级别都直接位于前一个级别之下,TreeView只能找到它的后代。

    例如,这可行:

    <TreeView>
      <TreeViewItem>
        <TreeViewItem />
      </TreeViewItem>
      ...
    </TreeView>
    

    所以这样:

    <HierarchicalDataTemplate TargetType="{x:Type MyItemType"} ItemsSource="{Binding subItems}">
      ...
    </HierarchicalDataTemplate>
    
    <TreeView ItemsSource="{Binding items}" />
    

    但是如果插入非TreeViewItems它将无法工作,如下所示:

    <TreeView>
      <TreeViewItem>
        <Border>
          <TreeViewItem/>
        </Border>
      </TreeViewItem>
    </TreeView>
    

    或者这个:

    <TreeView>
      <DockPanel>
        <TreeViewItem>
          <TreeViewItem/>
        </TreeViewItem>
      </DockPanel>
    </TreeView>
    

    最后两种情况将显示正常,但TreeView将不会看到TreeViewItems,因此其选择代码将被禁用。这会导致您描述的症状。

    我不知道你的情况是否属于这种情况,但我想我应该提一下以防万一。

答案 2 :(得分:0)

这是Amir答案的C#版本:

 private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
        {
            var treeViewItem = sender as TreeViewItem;
            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = true;
            }
        }