Silverlight树视图:保存展开/折叠状态

时间:2011-09-27 15:59:34

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

我在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树视图的任何内容......

有什么建议吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

考虑到您将数据实现为树的方式,为什么不将'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中有许多解决方法。

答案 1 :(得分:1)

这是我在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,它就可以工作。

答案 2 :(得分:0)

诀窍是使用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中使用的语法不完全相同,但它的工作原理并且运行良好!