也许我不太了解ObservableCollection。但据我所知,它与正常列表类似,但具有事件触发器,因此您可以对变化做出反应。C#奇怪Double ObservableCollection行为
所以我有这个Windows商店应用程序。在这个应用程序中,我有一个主要的BusinessModel类,它是我的客户端应用程序中所有数据的主要来源。当服务器在其他地方做了一些更改时,这些数据将被更新。在未来,我想让这个类更新ViewModels的特定数据更新等。 所以我也有一个ViewModel类,至少在我的PoC中至少包含了该列表的一个副本(在不久的将来此列表将包含该列表的丰富版本)。 既然它是一个副本,它们应该是两个独立的实例,并有自己的单独项目。 但是,当我更新ViewModel中的副本时,BusinessModel版本随之更改。 反之亦然。
我似乎无法弄清楚为什么会发生这种情况。下面你会发现类及其功能:
//the BusinessModel Class
public class ModelStuff : INotifyPropertyChanged
{
private ObservableCollection<DataObject> _modelStuff;
public ObservableCollection<DataObject> modelStuff
{
get
{
return _modelStuff;
}
set
{
_modelStuff = value;
NotifyPropertyChanged("modelStuff");
}
}
private static ModelStuff businessModel;
public static ModelStuff BusinessModel
{
get
{
if (businessModel == null)
{
businessModel = new ModelStuff();
}
return businessModel;
}
}
public ModelStuff()
{
modelStuff = new ObservableCollection<DataObject>();
modelStuff.Add(new DataObject(0));
modelStuff.Add(new DataObject(1));
modelStuff.Add(new DataObject(2));
modelStuff.Add(new DataObject(3));
modelStuff.Add(new DataObject(4));
modelStuff.Add(new DataObject(5));
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
//the ViewModel class
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<DataObject> _visibleStuff;
public ObservableCollection<DataObject> visibleStuff
{
get
{
return _visibleStuff;
}
set
{
_visibleStuff = value;
NotifyPropertyChanged("visibleStuff");
}
}
private static ViewModel tvm;
public static ViewModel TVM
{
get
{
if (tvm == null)
{
tvm = new ViewModel();
}
return tvm;
}
}
public ViewModel()
{
visibleStuff = new ObservableCollection<DataObject>(ModelStuff.BusinessModel.modelStuff.OrderBy(c => c.testNumber));
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
//the TestObjects
public class DataObject
{
public int testNumber { get; set; }
public String testStr { get; set; }
public DataObject(int i)
{
testNumber = i;
testStr = "testje";
}
}
//A randomly placed button invokes this function when clicked.
private void Button_Click(object sender, RoutedEventArgs e)
{
//do stuff here
int i0 = ModelStuff.BusinessModel.modelStuff[0].testNumber;
ViewModel.TVM.visibleStuff[0].testNumber = 100;
int i1 = ModelStuff.BusinessModel.modelStuff[0].testNumber;
//i1 has the value 100 in my logs! :S
}
//Second version but vice versa
private void Button_Click(object sender, RoutedEventArgs e)
{
//do stuff here
int i0 = ViewModel.TVM.visibleStuff[0].testNumber;
ModelStuff.BusinessModel.modelStuff[0].testNumber = 100;
int i1 = ViewModel.TVM.visibleStuff[0].testNumber;
//i1 has the value 100 in my logs! :S
}
哪里有我的推理哪里呢? 这是怎么回事? 更重要的是,我该如何防止这种行为?
这是否意味着它将一组指针复制到新集合?当我阅读msdn文档(http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx)时,实际上是这样说的:“初始化包含元素的ObservableCollection类的新实例从指定集合复制(!!)“。 –
元素*被复制。元素是参考! :) – Baldrick
为了扩展我的最后一条评论,没有(有注意事项!)执行对象的深层复制的一般方法。你必须自己编写代码(在类中),并且当你需要一个新的对象,它是一个现有对象的深层副本时调用它。 – Baldrick