C# 反序列化后IReactiveDerivedList已断开
当我创建一个带有C# 反序列化后IReactiveDerivedList已断开,c#,serialization,json.net,reactiveui,C#,Serialization,Json.net,Reactiveui,当我创建一个带有ReactiveList和IReactiveDerivedList的ViewModel,然后使用Json.net对其进行序列化和反序列化时,派生列表似乎被破坏了。我做错了什么 viewmodel: [DataContract] public class TestViewModel : ReactiveObject { [DataMember] public ReactiveList<int> List { get; } = new ReactiveLi
ReactiveList
和IReactiveDerivedList
的ViewModel,然后使用Json.net对其进行序列化和反序列化时,派生列表似乎被破坏了。我做错了什么
viewmodel:
[DataContract]
public class TestViewModel : ReactiveObject
{
[DataMember]
public ReactiveList<int> List { get; } = new ReactiveList<int>();
public IReactiveDerivedList<int> DerivedList { get; }
public TestViewModel()
{
//DerivedList contains all elements of List that are greater than 0.
DerivedList = List.CreateDerivedCollection(v => v, v => v > 0);
}
}
[DataContract]
公共类TestViewModel:ReactiveObject
{
[数据成员]
public ReactiveList List{get;}=new ReactiveList();
公共IReactiveDerivedList DerivedList{get;}
公共TestViewModel()
{
//DerivedList包含列表中大于0的所有元素。
DerivedList=List.CreateDerivedCollection(v=>v,v=>v>0);
}
}
序列化测试:
private void Example()
{
TestViewModel vm = new TestViewModel();
vm.List.Add(0);
vm.List.Add(1);
//vm.DerivedList now has 1 item
string json = JsonConvert.SerializeObject(vm);
TestViewModel clone = JsonConvert.DeserializeObject<TestViewModel>(json);
//vm.DerivedList now has 1 item
//clone.DerivedList now has 1 item
vm.List.Add(1);
clone.List.Add(1);
//vm.DerivedList now has 2 items
//clone.DerivedList now has 1 item
}
private void示例()
{
TestViewModel vm=新的TestViewModel();
vm.List.Add(0);
vm.List.Add(1);
//vm.DerivedList现在有1项
字符串json=JsonConvert.SerializeObject(vm);
TestViewModel clone=JsonConvert.DeserializeObject(json);
//vm.DerivedList现在有1项
//clone.DerivedList现在有1项
vm.List.Add(1);
克隆.列表.添加(1);
//vm.DerivedList现在有2项
//clone.DerivedList现在有1项
}
我认为这里的问题是,当ViewModel被反序列化时,用作派生列表源的ReactiveList也被反序列化,这就是问题所在
当您的TestViewModel被反序列化时,事件的顺序如下:
- 跑步。这是可观测的背景场
- TestViewModel构造函数将运行。这将设置派生集合,该集合订阅ReactiveList上的可观察对象
- 回调将运行。这将再次覆盖可观察的支持字段,覆盖其以前的值
[DataContract]
public class TestViewModel : ReactiveObject
{
[DataMember]
public ReactiveList<int> List { get; } = new ReactiveList<int>();
public IReactiveDerivedList<int> DerivedList { get; private set; }
public TestViewModel()
{
SetupRx();
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext context)
{
SetupRx();
}
private void SetupRx()
{
DerivedList?.Dispose();
DerivedList = List.CreateDerivedCollection(v => v, v => v > 0);
}
}
[DataContract]
公共类TestViewModel:ReactiveObject
{
[数据成员]
public ReactiveList List{get;}=new ReactiveList();
公共IReactiveDerivedList DerivedList{get;private set;}
公共TestViewModel()
{
SetupRx();
}
[已序列化]
内部已序列化(StreamingContext上下文)
{
SetupRx();
}
私有void SetupRx()
{
DerivedList?.Dispose();
DerivedList=List.CreateDerivedCollection(v=>v,v=>v>0);
}
}
经过更多测试后,即使使用此设置,ReactiveList似乎也有点问题。例如:如果在示例中使用viewmodel类型替换整数,并将筛选器设置为VM类型的属性,则派生列表将再次中断。在SetupRx()中将ChangeTrackingEnabled设置为true没有帮助。当您首先将ChangeTrackingEnabled设置为false,然后再次设置为true时,它确实起作用。在内部,这是因为_itemChanged在ReactiveList的setupRx()中被替换,切换changetracking会重置绑定。但这会产生一些非常丑陋的代码