在.net中使用ObservableCollection有什么用?
ObservableCollection是一个集合,它允许集合外部的代码知道何时发生对集合(添加,移动,删除)的更改。它在WPF和Silverlight中使用很多,但它的使用不仅限于此。代码可以添加事件处理程序以查看集合何时更改,然后通过事件处理程序做出一些额外的处理。这可能是更改UI或执行某些其他操作。
下面的代码并没有真正做任何事情,只是演示了如何在类中附加处理程序,然后使用事件args以某种方式对更改做出反应。 WPF已经有许多操作,比如刷新内置的UI,因此在使用ObservableCollections时可以免费获取它们
class Handler
{
private ObservableCollection<string> collection;
public Handler()
{
collection = new ObservableCollection<string>();
collection.CollectionChanged += HandleChange;
}
private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
{
foreach (var x in e.NewItems)
{
// do something
}
foreach (var y in e.OldItems)
{
//do something
}
if (e.Action == NotifyCollectionChangedAction.Move)
{
//do something
}
}
}
ObservableCollection
的工作方式基本上类似于常规集合,但它实现了接口:
因此,当您想知道集合何时发生变化时,它非常有用。触发一个事件,告诉用户添加/删除或移动了哪些条目。
更重要的是,在表单上使用数据绑定时,它们非常有用。
来自Pro C# 5.0 and the .NET 4.5 Framework
ObservableCollection<T>
类非常有用,因为它能够在内容以某种方式改变时通知外部对象(正如您可能猜到的那样,使用ReadOnlyObservableCollection<T>
非常相似,但本质上是只读的)。在许多方面,使用ObservableCollection<T>
与使用List<T>
完全相同,因为这两个类都实现了相同的核心接口。 ObservableCollection<T>
类的独特之处在于此类支持名为CollectionChanged
的事件。只要插入新项目,删除(或重新定位)当前项目,或者修改整个集合,就会触发此事件。与任何事件一样,CollectionChanged是根据委托来定义的,在这种情况下是委托NotifyCollectionChangedEventHandler
。该委托可以调用任何以对象作为第一个参数的方法,并将NotifyCollectionChangedEventArgs
作为第二个参数。考虑以下Main()方法,该方法填充包含Person对象的可观察集合并连接CollectionChanged
事件:
class Program
{
static void Main(string[] args)
{
// Make a collection to observe and add a few Person objects.
ObservableCollection<Person> people = new ObservableCollection<Person>()
{
new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
};
// Wire up the CollectionChanged event.
people.CollectionChanged += people_CollectionChanged;
// Now add a new item.
people.Add(new Person("Fred", "Smith", 32));
// Remove an item.
people.RemoveAt(0);
Console.ReadLine();
}
static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// What was the action that caused the event?
Console.WriteLine("Action for this event: {0}", e.Action);
// They removed something.
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
Console.WriteLine("Here are the OLD items:");
foreach (Person p in e.OldItems)
{
Console.WriteLine(p.ToString());
}
Console.WriteLine();
}
// They added something.
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
// Now show the NEW items that were inserted.
Console.WriteLine("Here are the NEW items:");
foreach (Person p in e.NewItems)
{
Console.WriteLine(p.ToString());
}
}
}
}
传入的NotifyCollectionChangedEventArgs
参数定义了两个重要的属性,OldItems
和NewItems
,它们将为您提供事件触发前当前在集合中的项目列表,以及更改中涉及的新项目。但是,您只想在正确的情况下检查这些列表。回想一下,当添加,删除,重新定位或重置项目时,可以触发CollectionChanged事件。要发现这些操作中的哪一个触发了事件,您可以使用NotifyCollectionChangedEventArgs的Action属性。可以针对NotifyCollectionChangedAction
枚举的以下任何成员测试Action属性:
public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}
对于那些想要一个没有任何代码的答案的人(繁荣时期),我会举手:
正常收藏 - 没有通知
我不时地去纽约,我的妻子要我买东西。所以我带了一个购物清单。这个清单上有很多东西,比如:
哈哈哈,我不会买那些东西。所以我将它们交叉并将它们从列表中删除,然后我添加:
所以我通常没有货物回家,她从不高兴。问题是,她不知道我从列表中删除了什么以及我添加了什么;她没有通知。
ObservableCollection - 进行更改时的通知
现在,每当我从列表中删除某些内容时:她会在她的手机上收到通知(即短信/电子邮件等)!
可观察的集合以同样的方式工作。如果您在其中添加或删除某些内容:会通知某人。当他们收到通知后,他们会打电话给你,你会得到满满的。当然后果可以通过事件处理程序自定义。
这总结了一切!
最大的用途之一是您可以将UI组件绑定到一个组件,如果集合的内容发生更改,它们将做出相应的响应。例如,如果将ListView的ItemsSource绑定到一个,则在修改集合时,ListView的内容将自动更新。
编辑:这是MSDN的一些示例代码:http://msdn.microsoft.com/en-us/library/ms748365.aspx
在C#中,将ListBox挂钩到集合可能非常简单
listBox.ItemsSource = NameListData;
虽然如果你没有将列表作为静态资源挂钩并定义了NameItemTemplate,你可能想要覆盖PersonName的ToString()。例如:
public override ToString()
{
return string.Format("{0} {1}", this.FirstName, this.LastName);
}
它是一个集合,用于通知UI在集合中进行更改,它支持自动通知。
主要用于WPF,
在哪里假设你有一个带有列表框的UI并添加按钮,当你点击他的按钮时,一个类型的对象会被添加到obseravablecollection,你将这个集合绑定到Listbox的ItemSource,所以只要你添加一个集合中的新项目,列表框将更新自身并在其中添加一个项目。
class FooObservableCollection : ObservableCollection<Foo>
{
protected override void InsertItem(int index, Foo item)
{
base.Add(index, Foo);
if (this.CollectionChanged != null)
this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
}
}
var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;
collection.Add(new Foo());
void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
Foo newItem = e.NewItems.OfType<Foo>().First();
}