ObservableCollection<T>(列表<T>)
ObservableCollection<T>(List<T>)
在msdn中你可以看到:"Initializes a new instance of the ObservableCollection class that contains elements copied from the specified list."
但我不明白这种行为:
我有一个 class 人。
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
那里的文档可能更清楚。对于值类型,如 int
,很明显 "copied" 的含义是:
Initializes a new instance of the ObservableCollection<T>
class that contains elements copied from the specified list.
然而,在你的情况下,你有一个引用类型。正是这个引用在两个列表之间被复制,所以两个列表都指向同一个底层对象,这意味着在两个列表中都可以看到任何更新。
In msdn you can read: "Initializes a new instance of the ObservableCollection class that contains elements copied from the specified list."
的确如此,但复制的是元素,而不是它们的内容 - 即元素的引用。
所以现在你有两个具有相同元素的集合。
当您从列表或 observableCollection 中询问一个元素时,您将获得对同一 person 实例的引用。
所以改变它显然会反映在两者上。
当您添加一个新项目时,您将其添加到一个特定的集合中,它不会被复制到另一个集合中。
因此,如果您查看 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
。
在msdn中你可以看到:"Initializes a new instance of the ObservableCollection class that contains elements copied from the specified list."
但我不明白这种行为:
我有一个 class 人。
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
那里的文档可能更清楚。对于值类型,如 int
,很明显 "copied" 的含义是:
Initializes a new instance of the
ObservableCollection<T>
class that contains elements copied from the specified list.
然而,在你的情况下,你有一个引用类型。正是这个引用在两个列表之间被复制,所以两个列表都指向同一个底层对象,这意味着在两个列表中都可以看到任何更新。
In msdn you can read: "Initializes a new instance of the ObservableCollection class that contains elements copied from the specified list."
的确如此,但复制的是元素,而不是它们的内容 - 即元素的引用。
所以现在你有两个具有相同元素的集合。
当您从列表或 observableCollection 中询问一个元素时,您将获得对同一 person 实例的引用。
所以改变它显然会反映在两者上。
当您添加一个新项目时,您将其添加到一个特定的集合中,它不会被复制到另一个集合中。
因此,如果您查看 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
。