c# - 当`List中`T`的属性发生变化时如何实现和触发事件` 在所属类中
问题描述
当所属类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
。
解决方案
我以前使用过这种模式,您基本上包装一个列表,扩展它以实现 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
参数将是引发事件的项目的实例。
推荐阅读
- sql-server - Excel VBA ADODB RecordSet 从 SQL Server 更改字段类型
- typescript - 带有回调函数的代码覆盖 istanbuljs,如 removeEventListener
- azure - Azure 搜索索引定义架构的版本控制
- python - 自定义闪屏窗口有时会冻结
- html - CKEditor 总是将内联 css 'font-size' 和 'font-family' 添加到 CKEDitor 中的源代码
- sql - 将现有的 MS SQL DB 移动到 Postgres 后的 PostgreSQL PK 序列和自动增量问题
- bloc - 为什么我们在 BLoC 架构中有冗余存储库?
- swiftui - SwiftUI 切换开关
- java - 从axis2MessageContext handleRequest方法WSO AM获取空json对象
- linux - 使用 shell 脚本根据随机 ID 号将数据分离到文件中