我在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树视图的任何内容......
有什么建议吗?
谢谢!
答案 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中使用的语法不完全相同,但它的工作原理并且运行良好!