【问题标题】:How to data-bind TreeViewItem.IsExpanded to a node data objects如何将 TreeViewItem.IsExpanded 数据绑定到节点数据对象
【发布时间】:2011-03-13 22:28:43
【问题描述】:

我有一个分层数据类,比如

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>

问题是如何将 TreeViewItem 的 IsExpanded 属性数据绑定到相应的 MyNode.IsExpanded 属性,以便我可以保留此信息。

提前谢谢你, 地法

【问题讨论】:

    标签: silverlight data-binding treeview silverlight-toolkit


    【解决方案1】:

    我不确定这是否适用于 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>
    

    【讨论】:

    • 这也是我的第一个猜测 :) 但是不,它在 Silverlight 中不起作用。
    【解决方案2】:

    如果我们像这样覆盖 TreeView 和 TreeViewItem 类,这是可能的:

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

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

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

    然后使用 ExTreeView 代替 TreeView,它会自动将数据绑定到分层数据项的 IsExpanded 属性。

    【讨论】:

      【解决方案3】:

      我不得不处理同样的问题,我采用了 MVVM 方式。

      首先,您要创建一个属性来表示该项目是否在您的视图模型中展开(这主要是 MVVM 帮助您的地方)。

      在您节点的视图模型中,只需添加类似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 来实现这个功能,我尝试过使用代码隐藏,因为它看起来更短(我很懒)而且结果是一团糟,而不仅仅是因为它需要一个递归函数,也因为隐藏的项目似乎不存在,直到它们的父项被打开。 这不愉快,这似乎是一种快速的方法,但我的经验使它更长。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-17
        • 2016-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多