Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Base / System / Collections / ObjectModel / ObservableCollection.cs / 1 / ObservableCollection.cs
//---------------------------------------------------------------------------- // //// Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // // // // Description: Implementation of an Collectionimplementing INotifyCollectionChanged // to notify listeners of dynamic changes of the list. // // See spec at http://avalon/connecteddata/Specs/Collection%20Interfaces.mht // // History: // 11/22/2004 : [....] - created // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Windows; namespace System.Collections.ObjectModel { /// /// Implementation of a dynamic data collection based on generic Collection<T>, /// implementing INotifyCollectionChanged to notify listeners /// when items get added, removed or the whole list is refreshed. /// [Serializable()] public class ObservableCollection: Collection , INotifyCollectionChanged, INotifyPropertyChanged { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors /// /// Initializes a new instance of ObservableCollection that is empty and has default initial capacity. /// public ObservableCollection() : base() { } ////// Initializes a new instance of the ObservableCollection class /// that contains elements copied from the specified list /// /// The list whose elements are copied to the new list. ////// The elements are copied onto the ObservableCollection in the /// same order they are read by the enumerator of the list. /// ///list is a null reference public ObservableCollection(Listlist) : base((list != null) ? new List (list.Count) : list) { // Workaround for VSWhidbey bug 562681 (tracked by Windows bug 1369339). // We should be able to simply call the base(list) ctor. But Collection // doesn't copy the list (contrary to the documentation) - it uses the // list directly as its storage. So we do the copying here. // CopyFrom(list); } /// /// Initializes a new instance of the ObservableCollection class that contains /// elements copied from the specified collection and has sufficient capacity /// to accommodate the number of elements copied. /// /// The collection whose elements are copied to the new list. ////// The elements are copied onto the ObservableCollection in the /// same order they are read by the enumerator of the collection. /// ///collection is a null reference public ObservableCollection(IEnumerablecollection) { if (collection == null) throw new ArgumentNullException("collection"); CopyFrom(collection); } private void CopyFrom(IEnumerable collection) { IList items = Items; if (collection != null && items != null) { using (IEnumerator enumerator = collection.GetEnumerator()) { while (enumerator.MoveNext()) { items.Add(enumerator.Current); } } } } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods /// /// Move item at oldIndex to newIndex. /// public void Move(int oldIndex, int newIndex) { MoveItem(oldIndex, newIndex); } #endregion Public Methods //------------------------------------------------------ // // Public Events // //------------------------------------------------------ #region Public Events //----------------------------------------------------- #region INotifyPropertyChanged implementation ////// PropertyChanged event (per event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add { PropertyChanged += value; } remove { PropertyChanged -= value; } } #endregion INotifyPropertyChanged implementation //------------------------------------------------------ ///). /// /// Occurs when the collection changes, either by adding or removing an item. /// ////// see [field:NonSerializedAttribute()] public virtual event NotifyCollectionChangedEventHandler CollectionChanged; #endregion Public Events //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods ////// /// Called by base class Collection<T> when the list is being cleared; /// raises a CollectionChanged event to any listeners. /// protected override void ClearItems() { CheckReentrancy(); base.ClearItems(); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionReset(); } ////// Called by base class Collection<T> when an item is removed from list; /// raises a CollectionChanged event to any listeners. /// protected override void RemoveItem(int index) { CheckReentrancy(); T removedItem = this[index]; base.RemoveItem(index); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index); } ////// Called by base class Collection<T> when an item is added to list; /// raises a CollectionChanged event to any listeners. /// protected override void InsertItem(int index, T item) { CheckReentrancy(); base.InsertItem(index, item); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); } ////// Called by base class Collection<T> when an item is set in list; /// raises a CollectionChanged event to any listeners. /// protected override void SetItem(int index, T item) { CheckReentrancy(); T originalItem = this[index]; base.SetItem(index, item); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index); } ////// Called by base class ObservableCollection<T> when an item is to be moved within the list; /// raises a CollectionChanged event to any listeners. /// protected virtual void MoveItem(int oldIndex, int newIndex) { CheckReentrancy(); T removedItem = this[oldIndex]; base.RemoveItem(oldIndex); base.InsertItem(newIndex, removedItem); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Move, removedItem, newIndex, oldIndex); } ////// Raises a PropertyChanged event (per protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) { PropertyChanged(this, e); } } ///). /// /// PropertyChanged event (per [field:NonSerializedAttribute()] protected virtual event PropertyChangedEventHandler PropertyChanged; ///). /// /// Raise CollectionChanged event to any listeners. /// Properties/methods modifying this ObservableCollection will raise /// a collection changed event through this virtual method. /// ////// When overriding this method, either call its base implementation /// or call protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (CollectionChanged != null) { using (BlockReentrancy()) { CollectionChanged(this, e); } } } ///to guard against reentrant collection changes. /// /// Disallow reentrant attempts to change this collection. E.g. a event handler /// of the CollectionChanged event is not allowed to make changes to this collection. /// ////// typical usage is to wrap e.g. a OnCollectionChanged call with a using() scope: /// protected IDisposable BlockReentrancy() { _monitor.Enter(); return _monitor; } ////// using (BlockReentrancy()) /// { /// CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, item, index)); /// } ///
///Check and assert for reentrant attempts to change this collection. ///raised when changing the collection /// while another collection change is still being notified to other listeners protected void CheckReentrancy() { if (_monitor.Busy) { // we can allow changes if there's only one listener - the problem // only arises if reentrant changes make the original event args // invalid for later listeners. This keeps existing code working // (e.g. Selector.SelectedItems). if ((CollectionChanged != null) && (CollectionChanged.GetInvocationList().Length > 1)) throw new InvalidOperationException(SR.Get(SRID.ObservableCollectionReentrancyNotAllowed)); } } #endregion Protected Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Helper to raise a PropertyChanged event />). /// private void OnPropertyChanged(string propertyName) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); } ////// Helper to raise CollectionChanged event with action == Reset to any listeners /// private void OnCollectionReset() { OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } #endregion Private Methods //----------------------------------------------------- // // Private Types // //------------------------------------------------------ #region Private Types // this class helps prevent reentrant calls [Serializable()] private class SimpleMonitor : IDisposable { public void Enter() { ++ _busyCount; } public void Dispose() { -- _busyCount; } public bool Busy { get { return _busyCount > 0; } } int _busyCount; } #endregion Private Types //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields private const string CountString = "Count"; // This must agree with Binding.IndexerName. It is declared separately // here so as to avoid a dependency on PresentationFramework.dll. private const string IndexerName = "Item[]"; private SimpleMonitor _monitor = new SimpleMonitor(); #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // // // // Description: Implementation of an Collectionimplementing INotifyCollectionChanged // to notify listeners of dynamic changes of the list. // // See spec at http://avalon/connecteddata/Specs/Collection%20Interfaces.mht // // History: // 11/22/2004 : [....] - created // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Windows; namespace System.Collections.ObjectModel { /// /// Implementation of a dynamic data collection based on generic Collection<T>, /// implementing INotifyCollectionChanged to notify listeners /// when items get added, removed or the whole list is refreshed. /// [Serializable()] public class ObservableCollection: Collection , INotifyCollectionChanged, INotifyPropertyChanged { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors /// /// Initializes a new instance of ObservableCollection that is empty and has default initial capacity. /// public ObservableCollection() : base() { } ////// Initializes a new instance of the ObservableCollection class /// that contains elements copied from the specified list /// /// The list whose elements are copied to the new list. ////// The elements are copied onto the ObservableCollection in the /// same order they are read by the enumerator of the list. /// ///list is a null reference public ObservableCollection(Listlist) : base((list != null) ? new List (list.Count) : list) { // Workaround for VSWhidbey bug 562681 (tracked by Windows bug 1369339). // We should be able to simply call the base(list) ctor. But Collection // doesn't copy the list (contrary to the documentation) - it uses the // list directly as its storage. So we do the copying here. // CopyFrom(list); } /// /// Initializes a new instance of the ObservableCollection class that contains /// elements copied from the specified collection and has sufficient capacity /// to accommodate the number of elements copied. /// /// The collection whose elements are copied to the new list. ////// The elements are copied onto the ObservableCollection in the /// same order they are read by the enumerator of the collection. /// ///collection is a null reference public ObservableCollection(IEnumerablecollection) { if (collection == null) throw new ArgumentNullException("collection"); CopyFrom(collection); } private void CopyFrom(IEnumerable collection) { IList items = Items; if (collection != null && items != null) { using (IEnumerator enumerator = collection.GetEnumerator()) { while (enumerator.MoveNext()) { items.Add(enumerator.Current); } } } } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods /// /// Move item at oldIndex to newIndex. /// public void Move(int oldIndex, int newIndex) { MoveItem(oldIndex, newIndex); } #endregion Public Methods //------------------------------------------------------ // // Public Events // //------------------------------------------------------ #region Public Events //----------------------------------------------------- #region INotifyPropertyChanged implementation ////// PropertyChanged event (per event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add { PropertyChanged += value; } remove { PropertyChanged -= value; } } #endregion INotifyPropertyChanged implementation //------------------------------------------------------ ///). /// /// Occurs when the collection changes, either by adding or removing an item. /// ////// see [field:NonSerializedAttribute()] public virtual event NotifyCollectionChangedEventHandler CollectionChanged; #endregion Public Events //----------------------------------------------------- // // Protected Methods // //----------------------------------------------------- #region Protected Methods ////// /// Called by base class Collection<T> when the list is being cleared; /// raises a CollectionChanged event to any listeners. /// protected override void ClearItems() { CheckReentrancy(); base.ClearItems(); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionReset(); } ////// Called by base class Collection<T> when an item is removed from list; /// raises a CollectionChanged event to any listeners. /// protected override void RemoveItem(int index) { CheckReentrancy(); T removedItem = this[index]; base.RemoveItem(index); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Remove, removedItem, index); } ////// Called by base class Collection<T> when an item is added to list; /// raises a CollectionChanged event to any listeners. /// protected override void InsertItem(int index, T item) { CheckReentrancy(); base.InsertItem(index, item); OnPropertyChanged(CountString); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index); } ////// Called by base class Collection<T> when an item is set in list; /// raises a CollectionChanged event to any listeners. /// protected override void SetItem(int index, T item) { CheckReentrancy(); T originalItem = this[index]; base.SetItem(index, item); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index); } ////// Called by base class ObservableCollection<T> when an item is to be moved within the list; /// raises a CollectionChanged event to any listeners. /// protected virtual void MoveItem(int oldIndex, int newIndex) { CheckReentrancy(); T removedItem = this[oldIndex]; base.RemoveItem(oldIndex); base.InsertItem(newIndex, removedItem); OnPropertyChanged(IndexerName); OnCollectionChanged(NotifyCollectionChangedAction.Move, removedItem, newIndex, oldIndex); } ////// Raises a PropertyChanged event (per protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) { PropertyChanged(this, e); } } ///). /// /// PropertyChanged event (per [field:NonSerializedAttribute()] protected virtual event PropertyChangedEventHandler PropertyChanged; ///). /// /// Raise CollectionChanged event to any listeners. /// Properties/methods modifying this ObservableCollection will raise /// a collection changed event through this virtual method. /// ////// When overriding this method, either call its base implementation /// or call protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (CollectionChanged != null) { using (BlockReentrancy()) { CollectionChanged(this, e); } } } ///to guard against reentrant collection changes. /// /// Disallow reentrant attempts to change this collection. E.g. a event handler /// of the CollectionChanged event is not allowed to make changes to this collection. /// ////// typical usage is to wrap e.g. a OnCollectionChanged call with a using() scope: /// protected IDisposable BlockReentrancy() { _monitor.Enter(); return _monitor; } ////// using (BlockReentrancy()) /// { /// CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, item, index)); /// } ///
///Check and assert for reentrant attempts to change this collection. ///raised when changing the collection /// while another collection change is still being notified to other listeners protected void CheckReentrancy() { if (_monitor.Busy) { // we can allow changes if there's only one listener - the problem // only arises if reentrant changes make the original event args // invalid for later listeners. This keeps existing code working // (e.g. Selector.SelectedItems). if ((CollectionChanged != null) && (CollectionChanged.GetInvocationList().Length > 1)) throw new InvalidOperationException(SR.Get(SRID.ObservableCollectionReentrancyNotAllowed)); } } #endregion Protected Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods ////// Helper to raise a PropertyChanged event />). /// private void OnPropertyChanged(string propertyName) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index, int oldIndex) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index, oldIndex)); } ////// Helper to raise CollectionChanged event to any listeners /// private void OnCollectionChanged(NotifyCollectionChangedAction action, object oldItem, object newItem, int index) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newItem, oldItem, index)); } ////// Helper to raise CollectionChanged event with action == Reset to any listeners /// private void OnCollectionReset() { OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } #endregion Private Methods //----------------------------------------------------- // // Private Types // //------------------------------------------------------ #region Private Types // this class helps prevent reentrant calls [Serializable()] private class SimpleMonitor : IDisposable { public void Enter() { ++ _busyCount; } public void Dispose() { -- _busyCount; } public bool Busy { get { return _busyCount > 0; } } int _busyCount; } #endregion Private Types //------------------------------------------------------ // // Private Fields // //----------------------------------------------------- #region Private Fields private const string CountString = "Count"; // This must agree with Binding.IndexerName. It is declared separately // here so as to avoid a dependency on PresentationFramework.dll. private const string IndexerName = "Item[]"; private SimpleMonitor _monitor = new SimpleMonitor(); #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XamlSerializerUtil.cs
- XamlInt32CollectionSerializer.cs
- EventProxy.cs
- ColumnCollection.cs
- ProfilePropertyMetadata.cs
- DataGridViewColumnHeaderCell.cs
- ButtonFlatAdapter.cs
- CmsInterop.cs
- XmlSchemaAnnotated.cs
- SQLStringStorage.cs
- FirewallWrapper.cs
- ItemCheckedEvent.cs
- PriorityQueue.cs
- GeneralTransformCollection.cs
- DBConnection.cs
- SMSvcHost.cs
- IssuanceTokenProviderState.cs
- TextEditorCopyPaste.cs
- OLEDB_Util.cs
- CapacityStreamGeometryContext.cs
- CurrentChangingEventManager.cs
- PersonalizationDictionary.cs
- HtmlLink.cs
- IDispatchConstantAttribute.cs
- HttpResponseHeader.cs
- Ops.cs
- RunInstallerAttribute.cs
- COM2ExtendedUITypeEditor.cs
- PaperSource.cs
- BrowserCapabilitiesFactoryBase.cs
- SoapFault.cs
- ToolStripActionList.cs
- TextEffect.cs
- InsufficientMemoryException.cs
- BitmapEffectRenderDataResource.cs
- JournalEntryListConverter.cs
- StickyNoteHelper.cs
- MetadataCache.cs
- PrivilegeNotHeldException.cs
- ProfileBuildProvider.cs
- MutexSecurity.cs
- RegexReplacement.cs
- ListBox.cs
- ExpressionCopier.cs
- HttpStaticObjectsCollectionWrapper.cs
- APCustomTypeDescriptor.cs
- RegexCompilationInfo.cs
- BitmapDownload.cs
- SqlMethodTransformer.cs
- ToolBarButton.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- PaginationProgressEventArgs.cs
- _emptywebproxy.cs
- DispatchProxy.cs
- WindowsGraphicsWrapper.cs
- DbConnectionInternal.cs
- HttpCacheVary.cs
- Convert.cs
- PackagePart.cs
- PasswordValidationException.cs
- MailSettingsSection.cs
- ExtensionSimplifierMarkupObject.cs
- HttpCacheVary.cs
- ZipIOLocalFileHeader.cs
- AuthorizationSection.cs
- ExpressionEditorAttribute.cs
- CallbackHandler.cs
- Html32TextWriter.cs
- IdentityHolder.cs
- DefinitionUpdate.cs
- FixedHyperLink.cs
- PersonalizableAttribute.cs
- DataGridViewComboBoxCell.cs
- WCFModelStrings.Designer.cs
- SqlTrackingWorkflowInstance.cs
- DiagnosticTrace.cs
- DataColumn.cs
- RegistryPermission.cs
- Label.cs
- WebBrowserUriTypeConverter.cs
- WebPartDisplayMode.cs
- SystemSounds.cs
- ChannelEndpointElement.cs
- _TransmitFileOverlappedAsyncResult.cs
- EventLogPermissionEntry.cs
- DefaultEvaluationContext.cs
- AppSettingsReader.cs
- RegisteredDisposeScript.cs
- MailBnfHelper.cs
- List.cs
- Expressions.cs
- BatchServiceHost.cs
- _ShellExpression.cs
- EmptyReadOnlyDictionaryInternal.cs
- XmlEncodedRawTextWriter.cs
- TraceHandlerErrorFormatter.cs
- ListControlConvertEventArgs.cs
- QuaternionRotation3D.cs
- X509UI.cs
- BitmapEffectDrawingContextWalker.cs