如何在列表视图的组头中保存IsExpanded状态

我有一个非常棘手的问题:

我正在使用ListView控件,其ItemsSource设置为CollectionViewSource,包括PropertyGroupDescription以对ListView元素进行分组。 CollectionViewSource看起来像这样:

        

在ListView中,我使用自定义组头,如下所示:

                          

如您所见,Expander的IsExpanded属性设置为true。 这意味着每当刷新ListView时,都会扩展所有Expander控件。

但是我想保存每个Expander的最后状态。 我无法找到一种方法来保存每个ObjectType的Expander状态列表。 我正在尝试使用绑定的HashTable和Converter,但是我没有将ObjectType作为ConverterParameter提供,因为它总是作为字符串传递。 但这可能不是解决方案。

有人可以给我一个解决方案的暗示或想法吗? 🙂

您可以使用Dictionary创建一个新类(例如,ObjectType作为bool值的键),并为其提供一个索引器:

  Dictionary expandStates = new Dictionary(); public bool this[ObjectType key] { get { if (!expandStates.ContainsKey(key)) return false; return expandStates[key]; } set { expandStates[key] = value; } } 

然后,在某个地方的ResourceDictionary中实例化它并将IsExpanded绑定到它,如下所示:

  

这可能会做得很好:让WPF调用代码并在需要时传递参数的好方法。 (WPF允许你将索引器中的子表达式放在绑定路径中对我来说是新闻 – 虽然不是很好!)

接受的答案是错误的,如评论中所述。 我写了以下行为,实现了所需的function:

 public class PersistGroupExpandedStateBehavior : Behavior { #region Static Fields public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register( "GroupName", typeof(object), typeof(PersistGroupExpandedStateBehavior), new PropertyMetadata(default(object))); private static readonly DependencyProperty ExpandedStateStoreProperty = DependencyProperty.RegisterAttached( "ExpandedStateStore", typeof(IDictionary), typeof(PersistGroupExpandedStateBehavior), new PropertyMetadata(default(IDictionary))); #endregion #region Public Properties public object GroupName { get { return (object)this.GetValue(GroupNameProperty); } set { this.SetValue(GroupNameProperty, value); } } #endregion #region Methods protected override void OnAttached() { base.OnAttached(); bool? expanded = this.GetExpandedState(); if (expanded != null) { this.AssociatedObject.IsExpanded = expanded.Value; } this.AssociatedObject.Expanded += this.OnExpanded; this.AssociatedObject.Collapsed += this.OnCollapsed; } protected override void OnDetaching() { this.AssociatedObject.Expanded -= this.OnExpanded; this.AssociatedObject.Collapsed -= this.OnCollapsed; base.OnDetaching(); } private ItemsControl FindItemsControl() { DependencyObject current = this.AssociatedObject; while (current != null && !(current is ItemsControl)) { current = VisualTreeHelper.GetParent(current); } if (current == null) { return null; } return current as ItemsControl; } private bool? GetExpandedState() { var dict = this.GetExpandedStateStore(); if (!dict.ContainsKey(this.GroupName)) { return null; } return dict[this.GroupName]; } private IDictionary GetExpandedStateStore() { ItemsControl itemsControl = this.FindItemsControl(); if (itemsControl == null) { throw new Exception( "Behavior needs to be attached to an Expander that is contained inside an ItemsControl"); } var dict = (IDictionary)itemsControl.GetValue(ExpandedStateStoreProperty); if (dict == null) { dict = new Dictionary(); itemsControl.SetValue(ExpandedStateStoreProperty, dict); } return dict; } private void OnCollapsed(object sender, RoutedEventArgs e) { this.SetExpanded(false); } private void OnExpanded(object sender, RoutedEventArgs e) { this.SetExpanded(true); } private void SetExpanded(bool expanded) { var dict = this.GetExpandedStateStore(); dict[this.GroupName] = expanded; } #endregion } 

它将字典附加到包含ItemsControl的字典中,该字典保存每个组项的展开状态。 这将是持久的,即使控件中的项目发生更改。

用法:

     ...  

标记的答案在.Net 4.5中不起作用。

一个简单的解决方案是添加一个

  private bool _isExpanded = true; public bool IsExpanded { get { return _isExpanded; } set { _isExpanded = value; } } 

ViewModel的属性(在本例中为CurrentListViewData保存的任何对象)

然后做:

  

在你的模板上。

像WPF一样简单有效