Древовидное представление Silverlight: сохранить развернутый - PullRequest
3 голосов
/ 27 сентября 2011

Я использую иерархическое древовидное представление в 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 ]

3 голосов
/ 27 сентября 2011

Учитывая способ реализации ваших данных в виде дерева, почему бы не связать свойство зависимостей 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 голос
/ 28 сентября 2011

Вот что я сделал для привязки к свойству TreeViewItem.IsExpanded.Во-первых, я добавил свойство IsExpanded в свой класс Node.

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, и он работает.

0 голосов
/ 10 февраля 2013

Хитрость заключается в том, чтобы использовать 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, но он работает и работает хорошо!

...