ObservableCollection 类 详解
生活随笔
收集整理的這篇文章主要介紹了
ObservableCollection 类 详解
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
假設(shè)您正在創(chuàng)建 Windows 窗體應(yīng)用程序,并且已將 DataGridView 控件綁定到標(biāo)準(zhǔn) List(Of Customer) 數(shù)據(jù)結(jié)構(gòu)。您希望能夠使網(wǎng)格中的項(xiàng)目與基礎(chǔ)數(shù)據(jù)源中的值保持同步。也就是說,如果其他代碼或其他窗體更改了 List 中用戶的數(shù)據(jù),您希望網(wǎng)格隨之更新并顯示修改的數(shù)據(jù)。 通常情況下,使用 Windows 窗體可以實(shí)現(xiàn)此目的。您可以進(jìn)行更新,但這種方法很受限制。例如,在正常情況下,您可以立即在網(wǎng)格中看到更新,但是如果有人向數(shù)據(jù)源中添加新行,則要向網(wǎng)格中添加新行可就沒那么容易了。Windows Presentation Foundation (WPF) 在 Microsoft .NET Framework 中添加了一些功能,所以您實(shí)際上可以可靠地使綁定控件與其數(shù)據(jù)源保持一致。我將在本文中演示如何使用 WPF 提供的 ObservableCollection 類。 利用 ObservableCollection 類,WPF 應(yīng)用程序可以使綁定控件與基礎(chǔ)數(shù)據(jù)源保持同步,但它還提供了更有用的信息,尤其是 ObservableCollection 類還可以在您添加、刪除、移動(dòng)、刷新或替換集合中的項(xiàng)目時(shí)引發(fā) CollectionChanged 事件。此功能還可以在您的窗口以外的代碼修改基礎(chǔ)數(shù)據(jù)時(shí)做出反應(yīng)。在本月的示例應(yīng)用程序中,您將了解到如何使用此信息,這正是接下來我要介紹的內(nèi)容。 ObservableCollection 類簡介 System.Collections.ObjectModel.ObservableCollection(Of T) 類從 Collection(Of T)(泛型集合的基類)繼承而來,可實(shí)現(xiàn) INotifyCollectionChanged 和 INotifyPropertyChanged 兩種接口。INotifyCollectionChanged 接口增加了集合的趣味性,同時(shí)也是允許綁定對(duì)象(和代碼)確定集合是否已發(fā)生更改的接口。 值得注意的是,雖然 ObservableCollection 類會(huì)廣播有關(guān)對(duì)其元素所做的更改的信息,但它并不了解也不關(guān)心對(duì)其元素的屬性所做的更改。也就是說,它并不關(guān)注有關(guān)其集合中項(xiàng)目的屬性更改通知。 如果您需要了解是否有人更改了集合中某個(gè)項(xiàng)目的屬性,則您將需要確保集合中的項(xiàng)目可以實(shí)現(xiàn) INotifyPropertyChanged 接口,并需要手動(dòng)附加這些對(duì)象的屬性更改事件處理程序。無論您如何更改此集合中的對(duì)象屬性,都不會(huì)觸發(fā)該集合的 PropertyChanged 事件。事實(shí)上,ObservableCollection 的 PropertyChanged 事件處理程序已受到保護(hù) — 除非您從此類中繼承并親自將其公開,否則您甚至無法對(duì)其做出反應(yīng)。在示例應(yīng)用程序中,我采用的方法比較簡單,讓客戶端應(yīng)用程序處理單個(gè)項(xiàng)目的更改事件,當(dāng)然,您也可以在繼承的集合中處理該集合內(nèi)每個(gè)項(xiàng)目的 PropertyChanged 事件。 如果您忽略了繼承的受保護(hù)成員(假設(shè)您已經(jīng)熟悉從其中派生 ObservableCollection 類的所有成員的 Collection 基類),則剩下的有趣成員僅有 Move 方法(允許您將某個(gè)成員移動(dòng)到集合中的新位置)和 CollectionChanged 事件(廣播有關(guān)對(duì)集合內(nèi)容所做的更改的信息)。繼續(xù)閱讀之前,您可能需要下載并安裝演示這些功能的示例 WPF 應(yīng)用程序。 查看示例 示例解決方案 ObservableCollectionTest 包含從 ObservableCollection 繼承而來的 CustomerList 類(請(qǐng)參見圖 1)。如您所料,CustomerList 類會(huì)公開包含 Customer 對(duì)象的 ObservableCollection 實(shí)例。但是,如果您檢查一下代碼,便會(huì)發(fā)現(xiàn)該類僅公開一個(gè)列表,所以該類的多個(gè)使用者分別檢索對(duì)同一集合的引用。(這是此次特定演示的關(guān)鍵,但對(duì)其他應(yīng)用程序來說不是必要的。)此類提供了一個(gè)私有構(gòu)造函數(shù),因此,檢索此類實(shí)例的唯一方法是調(diào)用共享的 GetList 方法,該方法用于分發(fā)現(xiàn)有集合實(shí)例: Private Shared list As New CustomerListPublic Shared Function GetList() As CustomerListReturn list
End Function
圖 1 CustomerList System.Collections.ObjectModel
Imports System.ComponentModelPublic Class CustomerListInherits ObservableCollection(Of Customer)Private Shared list As New CustomerListPublic Shared Function GetList() As CustomerListReturn listEnd FunctionPrivate Sub New()' Make the constructor private, enforcing the "factory" concept ' the only way to create an instance of this class is by calling' the GetList method.AddItems()End SubPublic Shared Sub Reset()list.ClearItems()list.AddItems()End SubPrivate Sub AddItems()Add(New Customer("Maria Anders"))Add(New Customer("Ana Trujillo"))Add(New Customer("Antonio Moreno"))End Sub
End Class
私有構(gòu)造函數(shù)調(diào)用 AddItems 方法;公開共享的 Reset 方法清除列表,然后調(diào)用 AddItems 方法。無論采用哪種方法,結(jié)果都是顯示集合中的三個(gè)使用方: Private Sub AddItems()Add(New Customer("Maria Anders"))Add(New Customer("Ana Trujillo"))Add(New Customer("Antonio Moreno"))
End Sub
在本示例中,Customer 類特別簡單(簡化到僅夠演示必要的功能)。圖 2 中顯示的類僅包含 Name 屬性,要不是該類可以實(shí)現(xiàn) INotifyPropertyChanged 接口,以便屬性值發(fā)生更改時(shí)會(huì)通知該類實(shí)例(包括數(shù)據(jù)綁定控件)的使用者,它根本不值得一提。 圖 2 具有 PropertyChanged 事件的 Customer 類 Imports System.ComponentModelPublic Class CustomerImplements INotifyPropertyChangedPublic Event PropertyChanged( _ByVal sender As Object, _ByVal e As PropertyChangedEventArgs) _Implements INotifyPropertyChanged.PropertyChangedProtected Overridable Sub OnPropertyChanged( _ByVal PropertyName As String)' Raise the event, and make this procedure' overridable, should someone want to inherit from' this class and override this behavior:RaiseEvent PropertyChanged( _Me, New PropertyChangedEventArgs(PropertyName))End SubPublic Sub New(ByVal Name As String)' Set the backing field so that you don't raise the ' PropertyChanged event when you first create the Customer._name = NameEnd SubPrivate _name As StringPublic Property Name() As StringGetReturn _nameEnd GetSet(ByVal value As String)If _name <> value Then_name = valueOnPropertyChanged("Name")End IfEnd SetEnd Property
End Class
某個(gè)類實(shí)現(xiàn) INotifyPropertyChanged 接口時(shí),它必須提供 PropertyChanged 事件: Public Event PropertyChanged( _ByVal sender As Object, _ByVal e As PropertyChangedEventArgs) _Implements INotifyPropertyChanged.PropertyChanged
為了引發(fā)使用標(biāo)準(zhǔn) .NET 設(shè)計(jì)模式的事件,Customer 類包含受保護(hù)且可覆蓋的 OnPropertyChanged 過程,該過程引發(fā)以下事件: Protected Overridable Sub OnPropertyChanged( _ByVal PropertyName As String)' Raise the event, and make this procedure' overridable, should someone want to inherit from' this class and override this behavior:RaiseEvent PropertyChanged( _Me, New PropertyChangedEventArgs(PropertyName))
End Sub
然后,在 Name 屬性的定義范圍內(nèi),屬性 setter 會(huì)在新值與屬性的當(dāng)前值不同時(shí)調(diào)用 OnPropertyChanged 方法: Private _name As StringPublic Property Name() As StringGetReturn _nameEnd GetSet(ByVal value As String)If _name <> value Then_name = valueOnPropertyChanged("Name")End IfEnd SetEnd Property
如果該類引發(fā)了 PropertyChanged 事件,則使用該類或該類的實(shí)例集合的代碼會(huì)對(duì) PropertyChanged 事件做出反應(yīng),然后基于屬性更改采取相應(yīng)的措施。(請(qǐng)注意,PropertyChangedEventArgs 類僅將 PropertyName 屬性添加到標(biāo)準(zhǔn)事件參數(shù),并不提供有關(guān)該屬性的舊值或新值的任何信息。稍后您會(huì)看到,示例應(yīng)用程序突破了這一限制,至少可以確定已更改屬性的新值。) 此示例還包含一個(gè)名為 MainWindow 的 WPF 窗口,如圖 3 所示。此窗口標(biāo)記中唯一重要的細(xì)節(jié)在于 ListBox 控件的定義,其中包括該控件的 ItemsSource 屬性的聲明式數(shù)據(jù)綁定。綁定指示該控件應(yīng)該從 MainWindow 類的 Data 屬性中獲取它的數(shù)據(jù),并且應(yīng)該顯示 Data 屬性中每個(gè)項(xiàng)目的 Name 屬性: <ListBox DisplayMemberPath="Name"ItemsSource="{Binding ElementName=MainWindow, Path=Data}" Grid.Column="3" Grid.RowSpan="3" Name="ItemListBox" Margin="5" />
圖 3 WPF 窗口示例(單擊圖像可查看大圖) MainWindow 的代碼隱藏類包括以下聲明: Public WithEvents Data As CustomerList = CustomerList.GetList()
此代碼在窗口中公開 CustomerList 實(shí)例的內(nèi)容,如圖 3 所示。 查看 codebehind 類中代碼的其余部分之前,您應(yīng)該在此處先停下來,體驗(yàn)一下應(yīng)用程序。因?yàn)榇翱谥械?ListBox 已綁定到從 ObservableCollection 繼承的類,所以您希望列表框始終顯示最新的集合內(nèi)容,而演示窗口證實(shí)了這一點(diǎn)。 此外,本示例顯示兩個(gè)單獨(dú)的主窗口實(shí)例,因?yàn)閮蓚€(gè)窗口上的 ListBox 控件都已綁定到同一 ObservableCollection 實(shí)例,所以在其中一個(gè)窗口中所做的更改會(huì)同時(shí)顯示在兩個(gè)窗口中。為了打開窗口中的兩個(gè)實(shí)例,Application.xaml 文件包含了以下標(biāo)記,指出應(yīng)用程序應(yīng)該首先運(yùn)行 Application_Startup 過程中的代碼: <Application x:Class="Application"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Startup="Application_Startup"><Application.Resources></Application.Resources>
</Application>
Application.xaml.vb 代碼隱藏文件包含以下啟動(dòng)代碼,用于創(chuàng)建兩個(gè) MainWindow.xaml 實(shí)例,每個(gè)實(shí)例都有自己的標(biāo)題: Private Sub Application_Startup( _ByVal sender As System.Object, _ByVal e As System.Windows.StartupEventArgs)Dim window As New MainWindowwindow.Title = "Observable Collection 1"window.Show()window = New MainWindowwindow.Title = "Observable Collection 2"window.Show()
End Sub
按照下列步驟測驗(yàn)示例應(yīng)用程序。 在 Visual Studio 2008 中,加載并運(yùn)行示例應(yīng)用程序。您會(huì)在同一窗口中看到兩個(gè)實(shí)例。 單擊以打開窗口左側(cè)的組合框。請(qǐng)注意,控件包含 0、1 和 2 這三個(gè)數(shù)字,分別對(duì)應(yīng)當(dāng)前的三個(gè)用戶。選擇 1,會(huì)選中 Ana Trujillo 并將她的名字復(fù)制到文本框。 在一個(gè)窗口中,單擊“刪除”。Ana Trujillo 會(huì)從兩個(gè)窗口中消失,因?yàn)閮蓚€(gè) ListBox 控件都已綁定到同一 ObservableCollection 實(shí)例,而綁定使得更新會(huì)立即顯示出來。再次打開組合框,請(qǐng)注意,現(xiàn)在僅會(huì)顯示兩個(gè)用戶。在每個(gè)窗口中都嘗試一下此操作,驗(yàn)證兩個(gè)實(shí)例是否都是最新的。 再兩次單擊“刪除”,刪除所有用戶。單擊“重置數(shù)據(jù)”重新填充兩個(gè)窗口中的列表。 在“添加新項(xiàng)”按鈕旁邊的文本框中,輸入您自己的名字,然后單擊“添加新項(xiàng)”。新名字即會(huì)顯示在兩個(gè) ListBox 控件中。單擊以打開組合框,并驗(yàn)證組合框現(xiàn)在是否包含 0 到 3 四個(gè)數(shù)字(每個(gè)數(shù)字分別對(duì)應(yīng)一個(gè)用戶)。驗(yàn)證兩個(gè)窗口中的組合框都已更改,很明顯,兩個(gè)窗口的類都收到了指示集合已更改的事件。 在一個(gè)窗口的 ListBox 中,選擇一個(gè)名字。在左側(cè)較低的文本框中,修改名字并單擊“更改”。首先,會(huì)出現(xiàn)一則警報(bào),指示您已更改了屬性,將其關(guān)閉后,您會(huì)立即看到兩個(gè)窗口中的名字都已更改(請(qǐng)參見圖 4)。 圖 4 捕獲集合中的數(shù)據(jù)更改事件(單擊圖像可查看大圖) 除了在您更改用戶名稱和 ComboBox 控件(其各個(gè)項(xiàng)目都根據(jù)集合中的用戶數(shù)量進(jìn)行相應(yīng)的更改)時(shí)出現(xiàn)的警報(bào)之外,示例窗口中的所有代碼都與此窗口的用戶界面有關(guān)。換言之,為保持 ListBox 控件與 ObservableCollection 實(shí)例同步而執(zhí)行的所有操作都可“自主”進(jìn)行,并且由 WPF 管理。 當(dāng)您添加新項(xiàng)目時(shí),ListBox 將自動(dòng)顯示完整列表。當(dāng)您更改項(xiàng)目時(shí),ListBox 將自動(dòng)顯示修改后的列表。當(dāng)您刪除項(xiàng)目時(shí),ListBox 將與基礎(chǔ)集合保持完全一致。換言之,對(duì)于將 ObservableCollection 類與 WPF 中的控件綁定這一任務(wù)來說,您可以很輕松地說“一切運(yùn)行正常”。 實(shí)際上,這種情況背后確實(shí)有一些“魔法”。將 ListBox 與 ObservableCollection 綁定后,實(shí)際上,WPF 實(shí)際上會(huì)創(chuàng)建一個(gè) CollectionView 實(shí)例,以顯示處理分組、排序和篩選等操作的數(shù)據(jù)的視圖。您可以在 ListBox 控件中看到集合的默認(rèn)視圖。您可以根據(jù)同一集合創(chuàng)建多個(gè) CollectionView 實(shí)例,在其中一個(gè) ListBox 控件中以不同的方式(如排序)顯示數(shù)據(jù)。雖然這個(gè)問題超出了我們的討論范圍,但是,如果您需要以多種視圖顯示同一集合,研究一下 CollectionView 類還是有必要的。有關(guān)詳細(xì)信息,請(qǐng)參閱 MSDN 上的 CollectionView 類信息。 查看代碼 由于 MainWindow 類定義 CustomerList 實(shí)例時(shí)使用的是 WithEvents 關(guān)鍵字,因此代碼可以處理 ObservableCollection 列表的事件,而無需用于手動(dòng)添加處理程序的代碼: Public WithEvents Data As CustomerList = CustomerList.GetList()
在代碼的“更改事件處理程序”區(qū)域中,您將看到 CollectionChanged 事件處理程序,它可以驗(yàn)證您在集合中是添加了還是刪除了項(xiàng)目。如果確實(shí)執(zhí)行了這些操作,代碼會(huì)設(shè)置組合框的數(shù)據(jù)源,并在窗口中啟用相應(yīng)的按鈕,如圖 5 所示。 圖 5 檢查更改的集合 Private Sub Data_CollectionChanged( _ByVal sender As Object, _ByVal e As NotifyCollectionChangedEventArgs) _Handles Data.CollectionChanged' Because the collection raises this event, you can modify your user ' interface on any window that displays controls bound to the data. On ' both windows, if you add or remove an item, all the controls update ' to indicate the new collection!' Did you add or remove an item in the collection?If e.Action = NotifyCollectionChangedAction.Add Or _e.Action = NotifyCollectionChangedAction.Remove Then' Set the list of integers in the combo box:SetComboDataSource()' Enable buttons as necessary:EnableButtons()End If
End Sub
這段簡單代碼的重點(diǎn)在于 NotifyCollectionChangedEventArgs 參數(shù)。此參數(shù)提供集合中發(fā)生更改的內(nèi)容的相關(guān)信息。此外,還提供了五個(gè)值得注意的屬性,如圖 6 所示。 圖 6 NotifyCollectionChangedEventArgs 參數(shù)
獲得所有這些信息之后,您的事件處理程序便可以準(zhǔn)確確定集合中執(zhí)行的哪些操作觸發(fā)了該事件。如果集合的大小發(fā)生更改,示例代碼將僅使用 Action 屬性更新 ComboBox 控件中的整數(shù)列表: If e.Action = NotifyCollectionChangedAction.Add Or _e.Action = NotifyCollectionChangedAction.Remove Then
雖然這與 ObservableCollection 類的討論無關(guān),但是,了解代碼如何填充 ComboBox 控件的索引列表也很有趣: Private Sub SetComboDataSource()' Set the list of integers shown in the ' combo box:ItemComboBox.ItemsSource = _Enumerable.Range(0, Data.Count)
End Sub
此代碼不是通過執(zhí)行某種循環(huán)來生成包含 0 至集合中編號(hào)最高的索引之間的整數(shù)的列表,而是直接調(diào)用 Enumerable.Range 方法來檢索從 0 開始且包含 Data.Count 值的整數(shù)集合。只要代碼將 ComboBox 控件的 ItemsSource 屬性設(shè)置為返回的集合即可 — 就是這么簡單!(如果想了解有關(guān) Enumerable 類的詳細(xì)信息,請(qǐng)閱讀我編寫的前兩期“高級(jí)基礎(chǔ)知識(shí)”專欄:LINQ Enumerable 類,第 1 部分和 LINQ Enumerable 類,第 2 部分。) 為了在您更改集合中某個(gè)項(xiàng)目的屬性后通知示例應(yīng)用程序,您必須再編寫一些代碼。每次某些代碼更改此類中的每個(gè)屬性值時(shí),都會(huì)引發(fā) PropertyChanged 事件。(當(dāng)然,這要由具體類的作者來確定更改屬性時(shí)會(huì)引發(fā) PropertyChanged 事件,因?yàn)樵撌录粫?huì)自動(dòng)發(fā)生。如您所知,Customer 類的 Name 屬性可以實(shí)現(xiàn)此目的。) 在 MainWindow 類中,您可以看到 HookupChangeEventHandler 過程,該過程可掛接單獨(dú) Customer 對(duì)象的 PropertyChanged 事件: Private Sub HookupChangeEventHandler(ByVal cust As Customer)' Add a PropertyChanged event handler for ' the specified Customer instance:AddHandler cust.PropertyChanged, _AddressOf HandlePropertyChanged
End Sub
HookupChangeEventHandlers 過程可掛接用戶的 ObservableCollection 類中每個(gè) Customer 對(duì)象的事件處理程序,如下所示: Private Sub HookupChangeEventHandlers()For Each cust As Customer In DataHookupChangeEventHandler(cust)Next
End Sub
當(dāng)窗口加載或您單擊“重置”按鈕時(shí),代碼將調(diào)用 HookupChangeEventHandlers 過程。如果單擊“刪除”,會(huì)同時(shí)從窗口中刪除集合中的項(xiàng)目和事件處理程序: ' From DeleteItemButton_ClickDim index As Integer = ItemComboBox.SelectedIndex
If index >= 0 ThenRemoveHandler Data.Item(index).PropertyChanged, _AddressOf HandlePropertyChangedData.RemoveAt(index)
如果單擊“添加新項(xiàng)”,代碼會(huì)創(chuàng)建新的用戶,并掛接其 PropertyChanged 事件: ' From NewItemButton_Clickcust = New Customer(NewItemTextBox.Text)
HookupChangeEventHandler(cust)
Data.Add(cust)
當(dāng)然,由于窗口將 ListBox 控件綁定到 ObservableCollection 實(shí)例,因此,所有這些更改會(huì)自動(dòng)顯示在窗口的兩個(gè)實(shí)例中,而無需借助任何代碼支持。實(shí)際上,只有在以編程方式在列表中添加或刪除用戶,然后掛接并響應(yīng)單個(gè)用戶中發(fā)生的更改時(shí)才需要使用代碼支持。 如果您確實(shí)更改了 Customer 類中某個(gè)屬性的值,客戶端應(yīng)用程序會(huì)通過 PropertyChanged 事件處理程序接收通知。請(qǐng)注意,HandlePropertyChanged 過程(如圖 7 所示)包含應(yīng)用程序中最復(fù)雜的代碼。由于更改通知只提供更改屬性的名稱,因此請(qǐng)務(wù)必記住,需要依靠代碼來檢索此屬性的當(dāng)前值(如果您需要此值)。 圖 7 使用 Reflection 的 HandlePropertyChanged Private Sub HandlePropertyChanged( _
ByVal sender As Object, _
ByVal e As PropertyChangedEventArgs)' In this particular application, you only want to bother with this ' code for the first window, although both will run the code. In this ' case, if the event was raised by the window whose title is ' "Observable Collection 1" then process the event:If Me.Title.EndsWith("1") ThenDim propName As String = e.PropertyNameDim myCustomer As Customer = CType(sender, Customer)' Unfortunately, no one hands you the old property value, or the new ' property value. You can use Reflection to retrieve the new property ' value, given the object that raised the event and the name of the ' property:Dim propInfo As System.Reflection.PropertyInfo = _GetType(Customer).GetProperty(propName)Dim value As Object = _propInfo.GetValue(myCustomer, Nothing)MessageBox.Show(String.Format( _"You changed the property '{0}' to '{1}'", _propName, value))End If
End Sub
此過程首先確保代碼只運(yùn)行一次 — 因?yàn)槟蜷_了窗口的兩個(gè)實(shí)例,否則代碼會(huì)分別針對(duì)每個(gè)實(shí)例運(yùn)行一次,但沒有必要顯示兩次警報(bào)。此代碼僅檢查標(biāo)題的最后一個(gè)字符(假設(shè)您沒有更改窗口的 Title 屬性),并限制僅在一個(gè)窗口中進(jìn)行操作: If Me.Title.EndsWith("1") Then'Code removed here…
End If
此代碼檢索并存儲(chǔ)發(fā)生更改的屬性的名稱以及對(duì)引發(fā)事件的對(duì)象(即當(dāng)前用戶)的引用: Dim propName As String = e.PropertyName
Dim myCustomer As Customer = CType(sender, Customer)
然后,獲得屬性的名稱和類型之后,代碼將使用 Reflection 檢索 System.Reflection.PropertyInfo 實(shí)例: Dim propInfo As System.Reflection.PropertyInfo = _GetType(Customer).GetProperty(propName)
獲得 PropertyInfo 對(duì)象和特定的 Customer 實(shí)例之后,代碼隨后就會(huì)檢索屬性的當(dāng)前值: Dim value As Object = _propInfo.GetValue(myCustomer, Nothing)
應(yīng)用程序中的其余代碼維護(hù)用戶界面,包括啟用/禁用按鈕以及使組合框和列表框保持同步等等。 雖然此應(yīng)用程序利用了 ObservableCollection 類提供的綁定支持,并響應(yīng) CollectionChanged 事件來更新用戶界面,但是您不必按照這種方法使用此類。因?yàn)樗鼤?huì)在其內(nèi)容發(fā)生更改時(shí)通知偵聽程序,所以您可以替換與 ObservableCollection 實(shí)例一起使用的任何 List 或 Collection 實(shí)例(即使您創(chuàng)建的不是 WPF 應(yīng)用程序),然后掛接事件處理程序以通知客戶端,集合的內(nèi)容已發(fā)生更改。 正如示例窗口在集合大小發(fā)生更改時(shí)更新與集合索引對(duì)應(yīng)的整數(shù)列表一樣,您可以使用任一必要的方法來響應(yīng)客戶端類的集合中發(fā)生的更改。但請(qǐng)記住,集合本身不會(huì)告訴您其子元素的屬性是否發(fā)生了更改。您必須掛接客戶端中的事件處理程序,以便客戶端在集合中的子元素的屬性發(fā)生更改時(shí)收到通知。 另請(qǐng)記住,您在示例應(yīng)用程序中看到的豐富數(shù)據(jù)綁定支持僅適用于 WPF 應(yīng)用程序。如果您創(chuàng)建的是 Windows 窗體應(yīng)用程序,那么當(dāng)集合發(fā)生更改時(shí),您仍然需要手動(dòng)刷新綁定到 ObservableCollection 實(shí)例的所有控件的綁定。另一方面,由于您會(huì)在集合發(fā)生更改時(shí)收到通知,因此現(xiàn)在至少可以實(shí)現(xiàn)此操作。
| Action | 檢索引發(fā)事件的操作的相關(guān)信息。此屬性包含 NotifyCollectionChangedAction 值,該值可以是 Add、Remove、Replace、Move 或 Reset。 |
| NewItems | 檢索更改集合時(shí)引入的新項(xiàng)目的列表。 |
| NewStartingIndex | 檢索發(fā)生更改的集合的索引。 |
| OldItems | 檢索受“替換”、“刪除”或“移動(dòng)”操作影響的舊項(xiàng)目列表。 |
| OldStartingIndex | 檢索執(zhí)行了“替換”、“刪除”或“移動(dòng)”操作的集合的索引。 |
轉(zhuǎn)載于:https://www.cnblogs.com/llkey/archive/2013/05/30/3108608.html
總結(jié)
以上是生活随笔為你收集整理的ObservableCollection 类 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive ALLOW_UNQUOTED_
- 下一篇: 选中条目android spinner的