C# 在不使用ObservableCollection的情况下将PropertyChanged抛出到列表中--可以这样做吗?

C# 在不使用ObservableCollection的情况下将PropertyChanged抛出到列表中--可以这样做吗?,c#,list,events,C#,List,Events,我有一个扩展了IList的类,我想将列表中的项目更改时触发的事件附加到该类 注意:我不能使用ObservableCollection。我不能使用ObservableCollection,因为我仅限于使用.NET 3.X,并且不能使用WindowsBase。正如您所知,ObservableCollection是在.NET3.X中的WindowsBase中实现的 我的问题很简单:当IList中的元素发生更改时,是否有一种方法触发事件 编辑:我应该提到,T实际上实现了INotifyProperty

我有一个扩展了IList的类,我想将列表中的项目更改时触发的事件附加到该类


注意:我不能使用ObservableCollection。我不能使用ObservableCollection,因为我仅限于使用.NET 3.X,并且不能使用WindowsBase。正如您所知,ObservableCollection是在.NET3.X中的WindowsBase中实现的


我的问题很简单:当IList中的元素发生更改时,是否有一种方法触发事件


编辑:我应该提到,
T
实际上实现了
INotifyPropertyChanged

我创建了一个
可观察列表
,通知您是否添加、删除、替换了某个项,以及该项本身是否已更改。项目类型必须实现INotifyPropertyChanged:

public class ObservableList<T> : IList<T>, IDisposable
    where T : INotifyPropertyChanged
{
    List<T> _innerList;
    bool _disposed;

    #region Notification

    public enum Action
    {
        Add,
        Remove,
        Replace,
        ItemPropertyChanged
    }

    public class ListOrItemChangedEventArgs : EventArgs
    {
        public ListOrItemChangedEventArgs(IList<T> oldItems, IList<T> newItems, int startingIndex, Action action, string propertyName)
        {
            StartingIndex = startingIndex;
            Action = action;
            OldItems = oldItems;
            NewItems = newItems;
        }

        public Action Action { get; private set; }

        public IList<T> OldItems { get; private set; }
        public IList<T> NewItems { get; private set; }

        public int StartingIndex { get; private set; }

        public string PropertyName { get; private set; }
    }

    public delegate void ListOrItemChangedEventHandler(ObservableList<T> sender, ListOrItemChangedEventArgs e);

    public event ListOrItemChangedEventHandler ListOrItemChanged;

    private void OnListOrItemChanged(IList<T> oldItems, IList<T> newItems, int startingIndex, Action action, string propertyName)
    {
        var eh = ListOrItemChanged;
        if (eh != null) {
            eh(this, new ListOrItemChangedEventArgs(oldItems, newItems, startingIndex, action, propertyName));
        }
    }

    void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        T item = (T)sender;
        OnListOrItemChanged(new List<T>(1) { item }, new List<T>(1) { item }, _innerList.IndexOf(item), Action.ItemPropertyChanged, e.PropertyName);
    }

    #endregion

    public ObservableList()
    {
        _innerList = new List<T>();
    }

    public ObservableList(int capacity)
    {
        _innerList = new List<T>(capacity);
    }

    public ObservableList(IEnumerable<T> items)
    {
        var coll = items as ICollection;
        if (coll == null) {
            _innerList = new List<T>();
        } else {
            _innerList = new List<T>(coll.Count);
        }
        foreach (T item in items) {
            _innerList.Add(item);
            if (item != null) {
                item.PropertyChanged += Item_PropertyChanged;
            }
        }
    }

    public void AddRange(IEnumerable<T> items)
    {
        int startIndex = _innerList.Count;
        _innerList.AddRange(items);
        foreach (T item in items) {
            if (item != null) {
                item.PropertyChanged += Item_PropertyChanged;
            }
        }
        OnListOrItemChanged(null, new List<T>(items), startIndex, Action.Add, null);
    }

    #region IList<T> Members

    public int IndexOf(T item)
    {
        return _innerList.IndexOf(item);
    }

    public void Insert(int index, T item)
    {
        _innerList.Insert(index, item);
        if (item != null) {
            item.PropertyChanged += Item_PropertyChanged;
        }
        OnListOrItemChanged(null, new List<T>(1) { item }, index, Action.Add, null);
    }

    public void RemoveAt(int index)
    {
        T item = _innerList[index];
        _innerList.RemoveAt(index);
        if (item != null) {
            item.PropertyChanged -= Item_PropertyChanged;
        }
        OnListOrItemChanged(new List<T>(1) { item }, null, index, Action.Remove, null);
    }

    public T this[int index]
    {
        get { return _innerList[index]; }
        set
        {
            T oldItem = _innerList[index];
            if (oldItem != null) {
                oldItem.PropertyChanged -= Item_PropertyChanged;
            }

            _innerList[index] = value;

            if (value != null) {
                value.PropertyChanged += Item_PropertyChanged;
            }
            OnListOrItemChanged(new List<T>(1) { oldItem }, new List<T>(1) { value }, index, Action.Replace, null);
        }
    }

    #endregion

    #region ICollection<T> Members

    public void Add(T item)
    {
        int startIndex = _innerList.Count;
        _innerList.Add(item);
        if (item != null) {
            item.PropertyChanged += Item_PropertyChanged;
        }
        OnListOrItemChanged(null, new List<T>(1) { item }, startIndex, Action.Add, null);
    }

    public void Clear()
    {
        foreach (T item in _innerList) {
            if (item != null) {
                item.PropertyChanged -= Item_PropertyChanged;
            }
        }
        var oldItems = _innerList;
        _innerList = new List<T>();
        OnListOrItemChanged(oldItems, null, 0, Action.Remove, null);
    }

    public bool Contains(T item)
    {
        return _innerList.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        _innerList.CopyTo(array, arrayIndex);
    }

    public int Count { get { return _innerList.Count; } }

    public bool IsReadOnly { get { return false; } }

    public bool Remove(T item)
    {
        int i = _innerList.IndexOf(item);
        if (i == -1) {
            return false;
        }
        item = _innerList[i]; // In case another instance is returned.
        if (item != null) {
            item.PropertyChanged -= Item_PropertyChanged;
        }
        _innerList.RemoveAt(i);
        OnListOrItemChanged(new List<T>(1) { item }, null, i, Action.Remove, null);
        return true;
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return _innerList.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _innerList.GetEnumerator();
    }

    #endregion

    #region IDisposable Members

    /// <summary>
    /// Removes PropertyChanged event handlers from all the items.
    /// </summary>
    public void Dispose()
    {
        if (!_disposed) {
            _disposed = true;
            foreach (T item in _innerList) {
                if (item != null) {
                    item.PropertyChanged -= Item_PropertyChanged;
                }
            }
        }
    }

    #endregion
}
公共类ObservableList:IList,IDisposable
其中T:INotifyPropertyChanged
{
列表innerList;
布卢;
#区域通知
公开枚举操作
{
添加
去除
代替
ItemPropertyChanged
}
公共类ListOrItemChangedEventArgs:EventArgs
{
public ListOrItemChangedEventArgs(IList oldItems、IList newItems、int startingIndex、Action Action、string propertyName)
{
起始指数=起始指数;
行动=行动;
OldItems=OldItems;
NewItems=NewItems;
}
公共操作操作{get;private set;}
公共IList OldItems{get;private set;}
公共IList NewItems{get;private set;}
public int StartingIndex{get;private set;}
公共字符串PropertyName{get;private set;}
}
公共委托无效ListOrItemChangedEventHandler(可观察列表发送者,ListOrItemChangedEventArgs e);
公共事件列表项变更Deventhandler列表项变更;
私有void OnListOrItemChanged(IList oldItems、IList newItems、int startingIndex、Action Action、string propertyName)
{
var eh=ListOrItemChanged;
如果(eh!=null){
eh(此、新列表项ChangedEventArgs(旧项、新项、开始索引、操作、属性名称));
}
}
无效项\u PropertyChanged(对象发送方,PropertyChangedEventArgs e)
{
T项=(T)发送方;
OnListOrItemChanged(新列表(1){item},新列表(1){item},_innerList.IndexOf(item),Action.ItemPropertyChanged,e.PropertyName);
}
#端区
公众观察者()
{
_innerList=新列表();
}
公共可观察列表(国际容量)
{
_innerList=新列表(容量);
}
公共观察列表(IEnumerable items)
{
var coll=作为ICollection的项目;
如果(coll==null){
_innerList=新列表();
}否则{
_innerList=新列表(coll.Count);
}
foreach(项目中的T项目){
_innerList.Add(项);
如果(项!=null){
item.PropertyChanged+=item_PropertyChanged;
}
}
}
公共无效添加范围(IEnumerable items)
{
int startIndex=\u innerList.Count;
_innerList.AddRange(项目);
foreach(项目中的T项目){
如果(项!=null){
item.PropertyChanged+=item_PropertyChanged;
}
}
OnListOrItemChanged(null,新列表(项),startIndex,Action.Add,null);
}
#国际劳工组织成员区域
公共整数索引(T项)
{
返回_innerList.IndexOf(项);
}
公共空白插入(整数索引,T项)
{
_插入(索引,项);
如果(项!=null){
item.PropertyChanged+=item_PropertyChanged;
}
OnListOrItemChanged(null,新列表(1){item},索引,Action.Add,null);
}
公共无效删除(整数索引)
{
T项=_内部列表[索引];
_RemoveAt(索引);
如果(项!=null){
item.PropertyChanged-=item_PropertyChanged;
}
OnListOrItemChanged(新列表(1){item},null,索引,Action.Remove,null);
}
公共T此[int索引]
{
获取{return _innerList[index];}
设置
{
T旧项=_内部列表[索引];
if(oldItem!=null){
oldItem.PropertyChanged-=项目_PropertyChanged;
}
_innerList[索引]=值;
if(值!=null){
value.PropertyChanged+=项目_PropertyChanged;
}
OnListOrItemChanged(新列表(1){oldItem},新列表(1){value},索引,Action.Replace,null);
}
}
#端区
#区域i集合成员
公共作废新增(T项)
{
int startIndex=\u innerList.Count;
_innerList.Add(项);
如果(项!=null){
item.PropertyChanged+=item_PropertyChanged;
}
OnListOrItemChanged(null,新列表(1){item},startIndex,Action.Add,null);
}
公共空间清除()
{
foreach(内部列表中的T项){
如果(项!=null){
item.PropertyChanged-=item_PropertyChanged;
}
}
var oldItems=\u innerList;
_innerList=新列表();
OnListOrItemChanged(oldItems,null,0,Action.Remove,null);
}
公共布尔包含(T项)
{
返回_innerList.Contains(项);
}
public void CopyTo(T[]数组,int arrayIndex)
{
_CopyTo(数组,arrayIndex);
}
公共整数计数{get{return\u innerList.Count;}}
public bool IsReadOnly{get{return false;}}
公共布尔删除(T项)
{
int i=_innerList.IndexOf(项);
如果(i==-1){
返回false;
}
item=_innerList[i];//以防返回另一个实例。
如果(项!=null){
项目1.PropertyC