如何在`List中的`T`属性发生更改时实现和触发事件 在拥有的班级内

问题描述 投票:2回答:1

如何在拥有类中的T中的List<T>属性发生更改时实现并触发事件

我的意思是,不是在收藏本身,而是在T的财产。

有什么模式怎么做?

我目前的代码

public class Section
{
    public string Title { get; set; }
    public List<Question> Questions { get; set; } = new List<Question>();

    public int AnsweredQuestion
    {
        get
        {
            return Questions.Count(x => x.State != DeviceNodeTechStateEnum.Undefined);
        }
    }

    public int NonAnsweredQuestion
    {
        get
        {

            return Questions.Count(x => x.State == DeviceNodeTechStateEnum.Undefined);
        }
    }

    public string QuestionStats
    {
        get
        {
            return string.Format("{0}/{1}", AnsweredQuestion, Questions.Count);
        }
    }
}

public class Question : INotifyPropertyChanged
{
    public Guid ID { get; set; }

    public string _note { get; set; }
    public string Note
    {
        get
        {
            return this._note;
        }

        set
        {
            if (value != this._note)
            {
                this._note = value;
                NotifyPropertyChanged();
            }
        }
    }

    private DeviceNodeTechStateEnum _state { get; set; }
    public DeviceNodeTechStateEnum State
    {
        get
        {
            return this._state;
        }

        set
        {
            if (value != this._state)
            {
                this._state = value;
                NotifyPropertyChanged();
            }
        }
    } 

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

基本上我需要知道public DeviceNodeTechStateEnum State是否有Section类的变化。

c# events collections
1个回答
6
投票

我之前使用过这种模式,你基本上把它包装起来,扩展它以实现INotifyPropertyChanged,并挂钩到列表中添加,插入或删除项目的任何方法,这样你就可以连接/取消项目PropertyChanged事件。

public class ItemPropertyChangedNotifyingList<T> : IList<T>, INotifyPropertyChanged where T : INotifyPropertyChanged
{
    private List<T> _listImplementation = new List<T>();

    public void Add(T item)
    {
        item.PropertyChanged += ItemOnPropertyChanged;
        _listImplementation.Add(item);
    }

    private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(sender, e);
    }

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

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable) _listImplementation).GetEnumerator();
    }

    public void Clear()
    {
        _listImplementation.ForEach(x => x.PropertyChanged -= ItemOnPropertyChanged);
        _listImplementation.Clear();
    }

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

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

    public bool Remove(T item)
    {
        item.PropertyChanged -= ItemOnPropertyChanged;
        return _listImplementation.Remove(item);
    }

    public int Count => _listImplementation.Count;

    public bool IsReadOnly => false;

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

    public void Insert(int index, T item)
    {
        item.PropertyChanged += ItemOnPropertyChanged;
        _listImplementation.Insert(index, item);
    }

   public void RemoveAt(int index)
    {
        if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index));
        _listImplementation[index].PropertyChanged -= ItemOnPropertyChanged;
        _listImplementation.RemoveAt(index);
    }

    public T this[int index]
    {
        get => _listImplementation[index];
        set => _listImplementation[index] = value;
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

处理此包装列表的PropertyChanged事件时,sender参数将是引发该事件的项的实例。

© www.soinside.com 2019 - 2024. All rights reserved.