开发者

do something before collection changes in observablecollection in wpf

开发者 https://www.devze.com 2023-03-12 04:42 出处:网络
I am not sure what i am trying to achieve is actually achievable or not. I have an observablecollection with me and its collectionchanged event is already been handled. What i want to do is I want to

I am not sure what i am trying to achieve is actually achievable or not.

I have an observablecollection with me and its collectionchanged event is already been handled. What i want to do is I want to make some changes in the existing list of objects in the observablecollection just before the collectionchanged event of the observablecollec开发者_运维百科tion gets fired. In other words i want to do something to the existing list of objects in the observablecollection before anyone adds or removes any object from the observablecollection. Something like handling the collectionchanging event but unfortunately there is not such event in observablecollection. I hope i have been clear enough.


Since you need to take action before the user changes the collection, I believe your CollectionChangedEvent is happening too late (the collection has already changed).

Instead, consider creating your own collection class which derives from ObservableCollection and then override the Add(), Insert(), and Remove() methods to do your additional processing before calling the base class implementation. You should be able to find examples of that on the web.

Here is some sample code to get you started. It derives from Collection:

public class MyCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
    public MyCollection(Collection<T> list)
        : base(list)
    {
    }

    public MyCollection()
        : base()
    {
    }

    #region INotifyCollectionChanged Members

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    protected void NotifyChanged(NotifyCollectionChangedEventArgs args)
    {
        NotifyCollectionChangedEventHandler handler = CollectionChanged;
        if (handler != null)
        {
            handler(this, args);
        }
    }
    #endregion

    public new void Add(T item)
    {
        // Do some additional processing here!

        base.Add(item);
        this.NotifyChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, base.Count-1));
        this.OnPropertyChanged("Count");
    }
}


You have been clear enough and the simple answer is: There is no such event and it is not possible.
The only solution I can think of is to derive from ObservableCollection<T> and implement that functionality yourself, i.e. in your implementation of Add you would first raise the CollectionChanging event and then call the Add method of the base class. You would do the same for all other relevant methods.

Having said all that, I am not really sure, this is the correct way to do it. Can you provide a reason why you would need this functionality?


Actually, the collection changed event in ObservableCollection is fired when (among other things) :

  • You add an item to the ObservableCollection.
  • You remove an item from the ObservableCollection.
  • You clear the ObservableCollection.

When I say "you", that means that if CollectionChanged Event occurs that means that "YOU" (understand : something in you application) has added, removed or cleared the list.

That being said, I guess you just have to find where those actions take place and put your code here...


You could create your own implementation of INotifyCollectionChanged that wraps the collection, listens to the event, changes the collection as appropriate and then sends the event along.

But when you change the collection, another event is raised, so you would have to make sure you're handling those events properly, probably by swallowing them


public class WantDoSomethingBeforeChangeGuy
{
    internal WantDoSomethingBeforeChangeGuy()
    {
        Members = new ImplMembers(this);
    }

    public ImplMembers Members { get; }

    private class ImplMembers : ObservableCollection<Artist>
    {
        private readonly WantDoSomethingBeforeChangeGuy _owner;

        public ImplMembers(WantDoSomethingBeforeChangeGuy owner)
        {
            _owner = owner;
        }

        protected override void ClearItems()
        {
            foreach (var item in this)
            {
                item.DoSomething(_owner);
            }
            base.ClearItems();        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消