How to save the IsExpanded state in group headers of a listview

前端 未结 3 872
不思量自难忘°
不思量自难忘° 2020-12-03 03:18

I have quite a tricky problem:

I am using a ListView control with the ItemsSource set to a CollectionViewSource including a PropertyGroupDescription to group the Lis

3条回答
  •  孤街浪徒
    2020-12-03 04:13

    The accepted answer is wrong as explained in the comments. I wrote the following behavior which achieves the desired functionality:

    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
    }
    

    It attaches a dictionary to the containing ItemsControl which saves the expanded state for every group item. This will be peristent, even if the items in the control changes.

    Usage:

    
        
            
        
        ...
    
    

提交回复
热议问题