WPF TreeView хочет выбрать первого потомка, когда выбран родитель - PullRequest
2 голосов
/ 07 мая 2009

Я использую модель презентации для реализации навигации в моем приложении с элементом управления TreeView. У меня есть свойство IsSelected TreeViewItem, привязанное к моей модели представления посредством двусторонней привязки. Когда выбран узел, у которого есть дочерние элементы, я хочу, чтобы был выбран первый дочерний элемент этого узла вместо того, по которому щелкали Кажется, что TreeViewItem не слушает событие изменения свойства, когда оно устанавливает свойство IsSelected в моей модели презентации. Первый дочерний узел выбран, но родительский узел не отменен. Вот код из моей модели презентации.

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 ]

1 голос
/ 19 ноября 2009

Еще одна возможность рассмотреть:

TreeView пытается сделать невозможным одновременный выбор двух TreeViewItems в дереве, поэтому это должно предотвратить это. Возможно, это ошибка в TreeView, но это также может быть проблемой при использовании TreeView.

Ради эффективности TreeView очень требователен к тому, как он находит TreeViewItems под ним. Алгоритм эффективно это (сделано в инкрементном режиме):

  1. Посмотри среди моих контейнеров предметов для объектов TreeView
  2. Посмотрите среди контейнеров элементов этих объектов TreeView для большего количества объектов TreeView
  3. Повторяйте шаг 3, пока не будет найдено больше объектов TreeView

Из-за этого TreeView может найти своих потомков, только если каждый уровень TreeViewItems находится непосредственно под предыдущим.

Например, это будет работать:

<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, поэтому его код выбора будет отключен. Это вызвало бы описанные вами симптомы.

Я не знаю, так ли это в вашем случае или нет, но я подумал, что должен упомянуть об этом на всякий случай.

1 голос
/ 18 ноября 2009

У меня была очень похожая проблема, и я обнаружил, что когда я выбираю дочерний элемент по коду, мне также нужно уделить внимание обертке 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
0 голосов
/ 30 мая 2018

Это C # версия ответа Амира:

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