We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Problem with maintaining TreeNode collapse state after updating property on collection object

I have an SfTreeGrid with an ItemSource that's an  ObservableCollection of classes that implements INotifyPropertyChanged. What I want to happen is when the property of one of the objects properties updates it'll update in the treegrid automatically. I try to achieve this by calling NotifyCollectionChangedEventArgs with NotifyCollectionChangedAction.Replace on the collection when one of their properties changes.

It does work but the problem is that if the node was expanded it will collapse, not maintaining state. Is there a nice way to resolve this?

3 Replies

MK Muthukumar Kalyanasundaram Syncfusion Team October 20, 2016 12:53 PM UTC

Hi Mattias,

Thank you for using Syncfusion products.
 
 
We had analyzed your reported “Problem with maintaining TreeNode collapse state after updating property on collection object” query. But, we are unable to understood your reported problem clearly. Based on your update, we have tried to update the value in child node and it did not get collapsed. We have checked the expand and collapse state in tree grid. We have expanded and updated the value in child node, it will maintain the same state (expanded state only). Please update some more information about your reported issue.  
  
For your referencewe have attached the tested sample in the below sample location, please revert by modifying the attached sample based on your application along with the replication procedureIt will be helpful for us to analyze further.    
 
Code Snippet: 
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // updating the single property in collection. 
    var items = (this.DataContext as ViewModel).PersonDetails; 
    items[0].Children[0].Id = 2000; 
                                       
                                        or 
 
    // to replace the collection  
    var collection = new ObservableCollection<PersonInfo>(); 
    collection.Add(new PersonInfo() { Id = 1012, FirstName = "Smith", LastName = "Ve", Salary = 29022, MyEyeColor = "Brown", Cake = "Cream", DOB = DateTime.Today, LikesCake = true }); 
    collection.Add(new PersonInfo() { Id = 1015, FirstName = "Willam", LastName = "Ku", Salary = 32990, MyEyeColor = "Brown", Cake = "Chocolate", DOB = DateTime.Today, LikesCake = false }); 
    items[1].Children = collection; 
             
} 
 
 
Please let us know if you have any concern. 
 
Regards, 
Muthukumar K 



MH Mattias Homde October 20, 2016 02:03 PM UTC

So I think we're talking about different things. Say that you have a collection of PersonInfo, and you show that information in the treegrid. Then you change say the name of an entry. What i'd like to do then is that the information would be refreshed and showed in the sfTreeGrid. It doesn't do that per default so you have to signal the ObservableCollection that a child object property has been changed, this is done by calling OnCollectionChanged with NotifyCollectionChangedAction.Replace , se snippet for collection below. But then the node is collapse, I think because it swaps out and creates a new tree node and doesn't maintain state. Perhaps there is some method that one can interject for whenever treenodes are created to set their collapsed state?

 public sealed class TrulyObservableCollection<T> : ObservableCollection<T>
    where T : INotifyPropertyChanged
    {
        public TrulyObservableCollection()
        {
            CollectionChanged += FullObservableCollectionCollectionChanged;
        }

        public TrulyObservableCollection(IEnumerable<T> pItems) : this()
        {
            foreach (var item in pItems)
            {
                Add(item);
            }
        }

        private void FullObservableCollectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (var item in e.NewItems)
                {
                    ((INotifyPropertyChanged)item).PropertyChanged += ItemPropertyChanged;
                }
            }
            if (e.OldItems != null)
            {
                foreach (var item in e.OldItems)
                {
                    ((INotifyPropertyChanged)item).PropertyChanged -= ItemPropertyChanged;
                }
            }
        }

        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, IndexOf((T)sender));
            OnCollectionChanged(args);
        }
    }


MK Muthukumar Kalyanasundaram Syncfusion Team October 21, 2016 12:11 PM UTC

Hi Mattias,   
  
Thanks for the update.   
  
As we mentioned in our previous update, the updated value is reflected in the tree grid properly. By default, if you implement INotifyPropertyChanged for the item, it will update the tree grid once property value is changed. So you don’t have to use OnCollectionChanged method with NotifyCollectionChangedAction.Replace. If you use this, it will create a new tree node and it will not retain the state (expand/collapse).  For your referencewe have attached sample in the below location. In this attached sample, while clicking the update value button, we have changed the first node’s FirstName property value and it will be reflected in the treeGrid also. If you still face the issue while updating the property value, please modify the attached sample based on your applicationIt will be helpful for us to analyze further.   

CodeSnippet:   
   
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // updating the single property in collection. 
    var items = (this.DataContext as ViewModel).PersonDetails; 
    items[1].FirstName = "David"; 
  
  
  
  
Regards,   
Muthukumar K.   


Loader.
Live Chat Icon For mobile
Up arrow icon