Home Forums WPF controls Xceed DataGrid for WPF INotifyCollectionChanged

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #25815 |

    Xceed Team
    It seems that the Grid does not support INotifyCollectionChanged fully.
    I have a Grid that Binds to A custom Collection Implementing INotifyCollectionChanged

    The grid accepts Items added to the Collection but not removed.
    I was deriving from ObservableCollection but wanted to Go more lightweight and control the CollectionChanged

    NotifyCollectionChangedEventArgs er = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item);
    CollectionChanged(this, er);

    But the item does not remove from the grid.
    If I run the event with a Reset Action then do an Add Action for each Item Added (Like ObservableCollection) It works fine

    Does the Grid support NotifyCollectionChangedAction.Remove
    If so are there any special conditions for using it?

    Imported from legacy forums. Posted by MiddleTommy (had 6958 views)

    User (Old forums)
    Member
    Post count: 23064

    I have derived from the GridControl and overridden the OnItemsChanged method

    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
    base.OnItemsChanged(e);
    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
    this.Items.Refresh();
    }

    This Works OK
    shouldnt the Grid refresh itself when Items are removed from the Collection?
    I peeked with Reflection at the code behind the OnItemsChanged and found that the
    Remove action only deals with SelectedItems.
    That seems odd behavior. Perhaps I have overridden the wrong method?
    I think it is a Bug

    Imported from legacy forums. Posted by MiddleTommy (had 639 views)

    Xceed Support
    Member
    Post count: 5658

    Hi Tommy,

    By the description of it, something effectively sounds strange.

    Let me ask some questions:

    – Is the DataGridControl grouped when you are removing the item?
    – Are you encapsulating your collection in a DataGridCollectionViewSource/DataGridCollectionView or are you setting it directly as the ItemsSource?

    – Would you be able to send us the repro application for this issue?

    Imported from legacy forums. Posted by Marcus [Xceed] (had 306 views)

    User (Old forums)
    Member
    Post count: 23064

    I am using no Grouping at all
    I am setting the ItemsSource to my Collection directly.
    I will work on a Sample App

    Imported from legacy forums. Posted by MiddleTommy (had 385 views)

    User (Old forums)
    Member
    Post count: 23064

    I sent the sample app

    Imported from legacy forums. Posted by MiddleTommy (had 344 views)

    Xceed Support
    Member
    Post count: 5658

    I’ll take a look at that and will let you know of my findings.

    THanks.

    Imported from legacy forums. Posted by Marcus [Xceed] (had 354 views)

    Xceed Support
    Member
    Post count: 5658

    Using your sample app, we were able to determine what the problem was:

    In your TestCollection class, you do not override the InsertItem, nor the RemoveItem methods. Those methods are called by Add/Remove methods on Collection<T>.

    Call your INotifyCollectionChanged handlers there and it will correct your problem

    Imported from legacy forums. Posted by Chris [Xceed] (had 531 views)

    User (Old forums)
    Member
    Post count: 23064

    I tried your suggestion and still didn’t work.
    So I saw that the RemoveItem method has the index as a parameter and not the item being removed.
    So I tried it again supplying the index of the removed item to the event and Then it worked.

    Logically It does not make sense that calling the Event from
    Add and Remove or from InsertItem and RemoveItem would make a difference on the functionality of your Grid.

    Your logic was off but it helped me find the real problem of suppling the index and item to the CollectionChanged event.
    Thank you

    Imported from legacy forums. Posted by MiddleTommy (had 609 views)

    Xceed Support
    Member
    Post count: 5658

    Hi Tommy,

    I’m glad we have been able to work this issue through.

    I’ve been looking at the project you sent a little as well and I tend to agree with Christian that there is a little something off with the implementation of INotifyCollectionChanged on top of the Collection<T> class.

    Effectively, when you declare new methods for Add() and Remove() and are placing some custom behavior in those functions ( in this case, the change notification ), people and code that uses your collection through the base class or through the standard IList or IList<T> interfaces will end-up NOT calling your functions (therefore no change notification), that is why Christ suggested moving the change notification to the 2 protected virtual functions.

    There are a lot of places in the system classes as well as in our classes where we have to rely on the IList or IList<T> interfaces to ensure a standardized behavior between several different object types, and it is well possible that part of the problem came from this.

    Imported from legacy forums. Posted by Marcus [Xceed] (had 445 views)

    User (Old forums)
    Member
    Post count: 23064

    Thankyou for your insight and suggestion I will consider that in my much larger collection
    implementation. But I have need to minimize the Collection Changed Process for some listeners and Only call CollectionChanged once with multiple Adds or Removes. unfortunately WPF only accepts single notification so I check who is listening then Post muti changes with one call or one at a time. So placing the Notification there does not work at the moment
    Perhaps I could create a queue and turn it on or off. Ill think about it.

    Food for thought – I was just reproducing the error and wrote a simple example class for the observable collection;

    My argument was that no matter where I notify the DataGridControl that my collection has changed it should work.

    Dont get me wrong I still think you guys are brilliant.

    Imported from legacy forums. Posted by MiddleTommy (had 708 views)

    Xceed Support
    Member
    Post count: 5658

    Actually, you are reminding me of an approach I took lately for a similar problem…

    While the exact implementation is not compatible with what you are trying to do, I can give you the basics of the design I chose.

    Basically, it resolved around using a IDisposable object to defer change events in a single batch:

    <code>
    using( myCustomCollection.DeferChangeNotification() )
    {
    do
    {
    //Process additions and/or removals
    }
    while( myExitCondition == true );

    }
    //when the IDisposable gets disposed, then you can send “batch” messages.
    </code>

    This approach is really easy to implement if additions or removals are made “sequentially” in the collection’s order but is much harder to do if additions or removal is made “all around” the collection’s content.

    I hope this helps you a little.

    <code>
    public class MyCollectionType
    {
    protected override void InsertItem( )//don’t remember the exact interface of the function
    {
    base.InsertItem();

    if( m_deferCount == 0 )
    {
    //Issue change notification right away
    }
    else
    {
    //queue the operation for later notification.
    }

    }

    private void ProcessDeferredOperations()
    {
    //process all deferred operations
    }

    private int m_deferCount = 0;

    private class MyCollectionDisposable : IDisposable
    {
    public MyCollectionDisposable( MyCollectionType parentCollection )
    {
    m_parent = parentCollection;

    m_parent.m_deferCount++;
    }

    void IDisposable.Dispose()
    {
    m_parent.m_deferCount–;

    if( m_parent.m_deferCount == 0 )
    {
    m_parent.ProcessDeferredOperations();
    }
    }

    private MyCollectionType m_parent;
    }
    }
    </code>

    Imported from legacy forums. Posted by Marcus [Xceed] (had 291 views)

    User (Old forums)
    Member
    Post count: 23064

    I didnt understand the difference of

    new vs override

    I read their definitions but it didnt compute properly
    now I understand and I Thank you again

    Thats what happens when you are self taught mostly from intellisense.

    But sometimes you can read all the books about the subject but not fully understand what the meaning is until you have a real world example to go by.

    I assumed that a new method would be called if the object was cast to an interface or base class because it is still the same object right? I was wrong

    Imported from legacy forums. Posted by MiddleTommy (had 8095 views)

Viewing 12 posts - 1 through 12 (of 12 total)
  • You must be logged in to reply to this topic.