【问题标题】:Silverlight treeview: save expanded/collapsed stateSilverlight 树视图:保存展开/折叠状态
【发布时间】:2011-09-27 15:59:34
【问题描述】:

我在 Silverlight 4 中使用分层树视图。这棵树可以经常清除和重建,具体取决于用户的操作。发生这种情况时,默认情况下树是折叠的,从用户的角度来看这可能很烦人。

所以,我想以某种方式保存哪些节点已展开,以便在清除并重新加载树后恢复其可视状态。

我的树视图是这样实现的:

xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:controls2="clr-namespace:System.Windows;assembly=System.Windows.Controls"

<controls:TreeView x:Name="Tree"
    ItemsSource="{Binding Source={StaticResource ViewModel}, Path=TreeStructure, Mode=OneWay}"
    ItemTemplate="{StaticResource hierarchicalTemplate}" />

<controls2:HierarchicalDataTemplate x:Key="hierarchicalTemplate" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Value.DisplayName}">
</controls2:HierarchicalDataTemplate>

我的树视图的 ItemsSource 绑定在 ObservableCollection TreeStructure 上;

Node 是一个看起来像这样的包装类:

public class Node
{
    public object Value { get; private set; }

    public ObservableCollection<Node> Children { get; private set; }

    public Node(object value)
    {
        Value = value;
        Children = new ObservableCollection<Node>();
    }
 }

相当标准的东西。我看到了一些 WPF 的解决方案,但我可以找到 Silverlight 树视图的任何东西......

有什么建议吗?

谢谢!

【问题讨论】:

    标签: c# silverlight silverlight-4.0 silverlight-toolkit


    【解决方案1】:

    鉴于您将数据实现为树的方式,为什么不将“TreeViewItem.IsExpanded”依赖属性绑定到您自己节点上的 bool 属性?

    它至少需要是一个 INotifyPropertyChanged 属性,因此 Node 需要实现 INotifyPropertyChanged。

    在 Silverlight 5 中,您可以设置这样的样式来绑定到 IsExpanded 属性:

    <Style TargetType="sdk:TreeViewItem" x:Key="itemStyle">
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
    </Style>
    

    并与

    一起使用
    ItemContainerStyle="{Binding Source={StaticResource itemStyle}}"
    

    在 Silverlight 4 中有许多解决方法。

    【讨论】:

    • 我喜欢这个建议!也许这是一个基本问题,但如何绑定 TreeViewItem.IsExpanded?我似乎无法从我的 XAML 中直接访问该属性。
    • @Tigel:我一直在尝试设置 IsExpanded 属性绑定的示例,但是您的特定 VM 和设置给我留下了空白树。您能否提供更多设置代码或完整的工作示例?
    • 是的,我得到了它的工作,我会在几个发布解决方案。感谢您为我指明正确的方向。 Silverlight 5 解决方案更加优雅!太糟糕了,我正在使用 SL4 :(
    【解决方案2】:

    这是我在 TreeViewItem.IsExpanded 属性上绑定的操作。首先,我在 Node 类中添加了一个 IsExpanded 属性。

    public class Node : INotifyPropertyChanged
    {
        public object Value { get; private set; }
    
        public ObservableCollection<Node> Children { get; private set; }
    
        private bool isExpanded;
        public bool IsExpanded
        {
            get
            {
                return this.isExpanded;
            }
            set
            {
                if (this.isExpanded != value)
                {
                    this.isExpanded = value;
                    NotifyPropertyChanged("IsExpanded");
                }
            }
        }
    
        public Node(object value)
        {
            Value = value;
            Children = new ObservableCollection<Node>();
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
     }
    

    之后,我对 TreeView 和 TreeViewItem 控件进行了子类化(我失去了我的树视图上的自定义主题,但无论如何......)

    public class BindableTreeView : TreeView
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            var itm = new BindableTreeViewItem();
            itm.SetBinding(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay });
    
            return itm;
        }
    }
    
    public class BindableTreeViewItem : TreeViewItem
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            var itm = new BindableTreeViewItem();
            itm.SetBinding(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay });
    
            return itm;
        }
    }
    

    在我的 XAML 中,我只需要使用 BindableTreeView 而不是 TreeView,它就可以工作。

    【讨论】:

      【解决方案3】:

      诀窍是使用来自here 的SetterValueBindingHelper。然后您的 XAML 将如下所示。请务必仔细复制我在下面的内容。

      <sdk:TreeView.ItemContainerStyle>
          <Style TargetType="sdk:TreeViewItem">
              <Setter Property="local:SetterValueBindingHelper.PropertyBinding">
                  <Setter.Value>
                      <local:SetterValueBindingHelper>
                          <local:SetterValueBindingHelper Property="IsSelected" Binding="{Binding Mode=TwoWay, Path=IsSelected}"/>
                          <local:SetterValueBindingHelper Property="IsExpanded" Binding="{Binding Mode=TwoWay, Path=IsExpanded}"/>
                      </local:SetterValueBindingHelper>
                  </Setter.Value>
              </Setter>
          </Style>
      </sdk:TreeView.ItemContainerStyle>
      

      语法与您在 WPF 中使用的语法不完全一样,但它可以工作,而且效果很好!

      【讨论】:

        猜你喜欢
        • 2012-01-19
        • 2017-11-24
        • 2010-12-15
        • 1970-01-01
        • 2011-05-10
        • 2013-08-17
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        相关资源
        最近更新 更多