C#奇怪的是Double ObservableCollection行为

时间:2014-02-20 08:51:16

标签: c# windows-store-apps observablecollection

也许我不太了解ObservableCollection。但据我所知,它与普通列表类似,但使用事件触发器,以便您可以对更改做出反应。

所以我有这个Windows商店应用程序。在这个应用程序中,我有一个主BusinessModel类,它是我的客户端应用程序中所有数据的主要来源。当服务器在其他地方进行了一些更改时,将更新此数据。将来我想让这个类更新ViewModel以获取特定的数据更新等。 所以我还有一个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
}

我的推理在哪里出错了? 为什么会这样? 更重要的是,我该如何防止这种行为?

1 个答案:

答案 0 :(得分:2)

据我所见,你的代码行:

  visibleStuff = new ObservableCollection<DataObject>(ModelStuff.BusinessModel.modelStuff.OrderBy(c => c.testNumber));

根本没有制作基础对象的副本。它将原始列表中的相同DataObject添加到新的ObservableCollection。

您需要单独克隆DataObject并将它们添加到新集合中。这样的事情应该这样做:

 visibleStuff = new ObservableCollection<DataObject>(ModelStuff.BusinessModel.modelStuff.OrderBy(c => c.testNumber).Select(i => new DataObject(i.testNumber)));