ObservableCollection и свойство элемента изменено

Мы писали это в WPF-чате:

public class OcPropertyChangedListener : INotifyPropertyChanged where T : INotifyPropertyChanged
{
    private readonly ObservableCollection _collection;
    private readonly string _propertyName;
    private readonly Dictionary _items = new Dictionary(new ObjectIdentityComparer());
    public OcPropertyChangedListener(ObservableCollection collection, string propertyName = "")
    {
        _collection = collection;
        _propertyName = propertyName ?? "";
        AddRange(collection);
        CollectionChangedEventManager.AddHandler(collection, CollectionChanged);
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                AddRange(e.NewItems.Cast());
                break;
            case NotifyCollectionChangedAction.Remove:
                RemoveRange(e.OldItems.Cast());
                break;
            case NotifyCollectionChangedAction.Replace:
                AddRange(e.NewItems.Cast());
                RemoveRange(e.OldItems.Cast());
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Reset:
                Reset();
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }

    }

    private void AddRange(IEnumerable newItems)
    {
        foreach (T item in newItems)
        {
            if (_items.ContainsKey(item))
            {
                _items[item]++;
            }
            else
            {
                _items.Add(item, 1);
                PropertyChangedEventManager.AddHandler(item, ChildPropertyChanged, _propertyName);
            }
        }
    }

    private void RemoveRange(IEnumerable oldItems)
    {
        foreach (T item in oldItems)
        {
            _items[item]--;
            if (_items[item] == 0)
            {
                _items.Remove(item);
                PropertyChangedEventManager.RemoveHandler(item, ChildPropertyChanged, _propertyName);
            }
        }
    }

    private void Reset()
    {
        foreach (T item in _items.Keys.ToList())
        {
            PropertyChangedEventManager.RemoveHandler(item, ChildPropertyChanged, _propertyName);
            _items.Remove(item);
        }
        AddRange(_collection);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(sender, e);
    }

    private class ObjectIdentityComparer : IEqualityComparer
    {
        public bool Equals(T x, T y)
        {
            return object.ReferenceEquals(x, y);
        }
        public int GetHashCode(T obj)
        {
            return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);
        }
    }
}

public static class OcPropertyChangedListener
{
    public static OcPropertyChangedListener Create(ObservableCollection collection, string propertyName = "") where T : INotifyPropertyChanged
    {
        return new OcPropertyChangedListener(collection, propertyName);
    }
}
  • Слабые события
  • Отслеживает добавление одного и того же элемента в коллекцию несколько раз.
  • Он всплывает ~ всплывающие ~ события изменения свойств детей.
  • Статический класс предназначен только для удобства.

Используйте c# это так:

var listener = OcPropertyChangedListener.Create(yourCollection);
listener.PropertyChanged += (sender, args) => { //do you stuff}

c#

observablecollection

2022-10-22T10:33:05+00:00
Вопросы с похожей тематикой, как у вопроса:

ObservableCollection и свойство элемента изменено