的ObservableCollection <T>(列表<T>)

时间:2017-03-13 17:14:44

标签: c# observablecollection

在msdn中,您可以阅读:&#34;初始化ObservableCollection类的新实例,该实例包含从指定列表中复制的元素。&#34;

但我不明白这种行为:

我有一个班级人员。

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }

    public override string ToString()
    {
        return Firstname + " " + Lastname;
    }
}

现在我创建了一个人员列表。 然后我创建一个ObservableCollection,它应该包含列表中复制的元素。

然后我在列表中更改一个人,在ObservableCollection中更改一个人。 这两个变化都反映在两个集合中。为什么呢?

最后,我将一个人添加到列表中,一个添加到OC。 添加的项目仅在相关集合中反映

public partial class MainWindow : Window
{
    private List<Person> PersonList{ get; set; }
    private ObservableCollection<Person> PersonObservableCollection { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        FillCollections();

        listbox1.ItemsSource = PersonList;
        listbox2.ItemsSource = PersonObservableCollection;            
    }


    private void FillCollections()
    {
        PersonList = LoadDataPerson();
        PersonObservableCollection = new ObservableCollection<Person>(PersonList);

        // Adding a person to the List.
        PersonList.Add(new Person() { Firstname = "added to List",});

        // Adding a person to the ObservableCollection.
        PersonObservableCollection.Add(new Person() { Firstname = "added to Observable Collection" });


        // Changing then name of the first person in the List
        Person p1 = PersonList[0];
        p1.Lastname = "changed in List";

        // Changing the name of the second person in the ObservableList
        Person p2 = PersonObservableCollection[1];
        p2.Lastname = "changed in ObservableCollection";
    }


    private List<Person> LoadDataPerson()
    {
        List<Person> personen = new List<Person>();
        personen.Add(new Person() { Firstname = "John"});
        personen.Add(new Person() { Firstname = "Will"});
        personen.Add(new Person() { Firstname = "Sam" });
        return personen;
    }
}

XAML:

<Window x:Class="ObservableCollection.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ObservableCollection"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <ListBox Grid.Column="0" x:Name="listbox1"/>
    <ListBox Grid.Column="1" x:Name="listbox2"/>

</Grid>

输出如下: Output

3 个答案:

答案 0 :(得分:1)

那里的文件可能更清晰。对于值类型,例如int,显而易见的是&#34;复制&#34;意思是:

  

初始化ObservableCollection<T>类的新实例,该实例包含从指定列表复制的元素。

但是,在您的情况下,您有一个引用类型。它是在两个列表之间复制的引用,因此两个列表都指向相同的底层对象,这意味着两者都可以看到任何更新。

答案 1 :(得分:1)

  

在msdn中,您可以阅读:“初始化ObservableCollection类的新实例,该实例包含从指定列表复制的元素。”

这是事实,但复制的是元素,而不是它们的内容 - 意味着元素的参考。

所以现在你有两个具有相同元素的集合 当您要求列表中的元素或observableCollection时,您将获得对同一个人实例的引用。 所以改变它会显然反映在两者中。

添加新项目时,将其添加到特定集合中,不会将其复制到另一个项目。

答案 2 :(得分:0)

因此,如果您查看source code for this正在操纵基础列表。

    protected virtual void InsertItem(int index, T item) {
        items.Insert(index, item);
    }

这只是一个示例,items是私有字段:

public class Collection<T>: IList<T>, IList, IReadOnlyList<T>
{
    IList<T> items;
    [NonSerialized]
    private Object _syncRoot;

    public Collection() {
        items = new List<T>();
    }

    public Collection(IList<T> list) {
        if (list == null) {
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
        }
        items = list;
    }

正如您可以清楚地看到修改两个集合(可观察的集合和原始集合)时,更改将反映在两者中。

所有ObservableCollection正在顶部进行代理INotifyPropertyChanged