1.ObservableCollection序列化
情景:定义了A类、B类;
A类里面有ObservableCollection<B>类型的属性,假设这个属性名称为BList;
ObservableCollection<MotionIntervalSegmentation> motionIntervalSegmentation;
[Browsable(true)]
[Display(Description = "低速区间", GroupName = "通用", Name = "低速区间", Order = 15)]
public ObservableCollection<MotionIntervalSegmentation> MotionIntervalSegmentationList
{
get => motionIntervalSegmentation;
set
{
if (value != motionIntervalSegmentation)
{
OnPropertyChanged("MotionIntervalSegmentationList", motionIntervalSegmentation, value);
motionIntervalSegmentation = value;
}
}
}
在调用Newtonsoft.Json库进行Json序列化时,在生成的Json字符串中发现BList里面每一个B类型实体的属性都丢了;
尝试给B类添加了Serializable和DataContract,没效果;
最后给B类的每个属性添加了DataMember特性,可以正常序列化:
private int _startPoint;
[DataMember]//必须加 *^____^*
[Browsable(true)]
[Display(Description = "区间起点", GroupName = "通用", Name = "起点", Order = 1)]
public int StartPoint
{
get { return _startPoint; }
set { this.RaiseAndSetIfChanged(ref _startPoint, value); }
}
添加了[DataMember]就不用给类添加[DataContract],反之不行;
2.监听ObservableCollection链表内元素变化
正常情况下,一个ObservableCollection<T> 类型的属性:
private ObservableCollection<ExposureParam> _exposureParams;
public ObservableCollection<ExposureParam> ExposureParams
{
get => _exposureParams;
set => this.RaiseAndSetIfChanged(ref _exposureParams, value);
}
只有当这个集合初始化、删除或者添加元素的时候才会进入Set赋值方法。
场景:界面的Datagrid绑定了后台的一个实体链表、PropertyGrid绑定的实体中有链表类型属性等,在改变链表中单个元素的属性时,想要监测改变的新值。
实现:
比如有一个字段:public ObservableCollection<ExposureParam> ExposureParams;
ObservableCollection类型有CollectionChanged事件,实现思路是监听ExposureParam类的属性变化,然后传递给ObservableCollection的CollectionChanged事件;
C#中 INotifyPropertyChanged接口可以实现监听一个类的属性变化;
然后在一个链表初始化的时候把每个元素的属性改变事件与链表的CollectionChanged事件关联起来,这里给出实现:
public class HiddenCountCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
{
/// <summary>
/// 隐藏Count属性,不在属性编辑框显示
/// </summary>
[Browsable(false)]
public new int Count => base.Count;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
RegisterPropertyChanged(e.NewItems);
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
UnRegisterPropertyChanged(e.OldItems);
}
else if (e.Action == NotifyCollectionChangedAction.Replace)
{
UnRegisterPropertyChanged(e.OldItems);
RegisterPropertyChanged(e.NewItems);
}
base.OnCollectionChanged(e);
}
protected override void ClearItems()
{
UnRegisterPropertyChanged(this);
base.ClearItems();
}
private void RegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void UnRegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//launch an event Reset with name of property changed
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
其中我重写了父类的Count属性,并且添加了[Browsable(false)]特性,就不会在属性编辑框(PropertyGrid)中显示Count一栏,遇到的话你就懂了;
引用:C# 扩展集合ObservableCollection使集合在添加、删除、值变更后触发事件 - dotnet编程大全的文章 - 知乎
https://zhuanlan.zhihu.com/p/453099277