Как привязать данные TreeViewItem.IsExpanded к узлу данных объектов - PullRequest
4 голосов
/ 09 июля 2010

У меня есть иерархические классы данных, такие как

public class MyNode 
{
   public string Name { get; set;}
   public bool IsExpanded { get; set;}
   public List<MyNode> Nodes { get; set;}
}

Я мог бы определить HierarchicalDataTemplate для привязки классов MyNode к TreeView.

<sdk:TreeView ItemsSource="{Binding RootNodes}">
  <sdk:TreeView.ItemTemplate>
    <sdk:HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
      <TextBlock Text="{Binding Name}" />
    </sdk:HierarchicalDataTemplate>
  </sdk:TreeView.ItemTemplate>
</sdk:TreeView>

Вопрос в том, как привязать свойство IsExpanded объекта TreeViewItem к соответствующему свойству MyNode.IsExpanded, чтобы я мог сохранить эту информацию.

Заранее спасибо, Lex

Ответы [ 3 ]

4 голосов
/ 09 июля 2010

Я не уверен, работает ли это в Silverlight или нет, но в WPF вы можете привязать к IsExpanded, используя стиль:

<sdk:TreeView ItemsSource="{Binding RootNodes}">
    <sdk:TreeView.Resources>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
        </Style>
    </sdk:TreeView.Resources>
    <sdk:TreeView.ItemTemplate>
        <sdk:HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
            <TextBlock Text="{Binding Name}" />
        </sdk:HierarchicalDataTemplate>
    </sdk:TreeView.ItemTemplate>
</sdk:TreeView>
2 голосов
/ 15 февраля 2014

Мне пришлось столкнуться с той же проблемой, и я сделал MVVM-способ.

Во-первых, вы хотите создать свойство, которое будет представлять, развернут ли элемент в вашей модели представления (в основном это помогает MVVM).

В view-модели вашего узла просто добавьте что-то вроде Boolean IsNodeExpanded { get; set; }.
Внимание: выше только интерфейс! Вы должны уведомить об изменениях с помощью INotifyPropertyChanged.PropertyChanged, , иначе это не будет работать!

Затем вы хотите подключить его к вашему представлению, и это очень похоже на то, что здесь предложил Энди; использовать стили. Однако его разметки было недостаточно для меня (одна из причин в том, что она не работала).
То, что вы на самом деле хотите сделать, это поместить стиль в древовидное представление ItemContainerStyle.

<TreeView ...>
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="{Binding Path=IsNodeExpanded, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

И в моем случае это сработало.

<ч /> Примечание 1: избавьте себя от головной боли и убедитесь, что привязка в вышеприведенном стиле является двусторонней привязкой в ​​том виде, как она представлена. Некоторое время назад у меня был проект, когда мне пришлось сделать это заново, я забыл сделать его двусторонним, и даже отладка не помогла.

Примечание 2: Вы должны использовать MVVM для этой функции, я попытался использовать для нее кодовый код, потому что он казался короче (я ленивый) и оказался длинным беспорядком, а не просто потому что это требует рекурсивной функции, а также потому, что скрытые элементы, кажется, не существуют, пока их родитель не открыт. Это не приятно , и это может показаться быстрым способом сделать это, но мой опыт сделал это намного дольше.

1 голос
/ 25 ноября 2010

Это возможно, если мы переопределим классы TreeView и TreeViewItem следующим образом:

<code>public class ExTreeView : System.Windows.Controls.TreeView
{
  protected override DependencyObject GetContainerForItemOverride()
  {
    return new ExTreeViewItem();
  }
}</p>

<p>public class ExTreeViewItem : System.Windows.Controls.TreeViewItem
{
  public ExTreeViewItem()
  {
    SetBinding(IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay });
  }</p>

<p>protected override DependencyObject GetContainerForItemOverride()
  {
    return new ExTreeViewItem();
  }
}

Затем используйте ExTreeView вместо TreeView, он автоматически свяжет данные со свойством IsExpanded элемента иерархических данных.

...