Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / System / Collections / ObjectModel / ObservableCollection.cs / 1 / ObservableCollection.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) 2003 by Microsoft Corporation. All rights reserved.
//
//
//
// Description: Implementation of an Collection implementing INotifyCollectionChanged
// to notify listeners of dynamic changes of the list.
//
// See spec at [....]/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(List list)
: 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.
//
IList items = Items;
if (list != null && items != null)
{
using (IEnumerator enumerator = list.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
///
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 ).
///
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 to guard against reentrant collection changes.
///
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
using (BlockReentrancy())
{
CollectionChanged(this, e);
}
}
}
///
/// 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:
///
/// using (BlockReentrancy())
/// {
/// CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, item, index));
/// }
///
///
protected IDisposable BlockReentrancy()
{
_monitor.Enter();
return _monitor;
}
/// 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
- FixedHyperLink.cs
- PropertyRef.cs
- InlineCollection.cs
- ConfigXmlText.cs
- ExcCanonicalXml.cs
- EventSourceCreationData.cs
- NonParentingControl.cs
- CngProperty.cs
- ProfileBuildProvider.cs
- ExpandCollapsePattern.cs
- PartialList.cs
- LogicalTreeHelper.cs
- XmlCharCheckingWriter.cs
- XamlReaderConstants.cs
- TableHeaderCell.cs
- DiscreteKeyFrames.cs
- InvokeWebServiceDesigner.cs
- ResourceManagerWrapper.cs
- SafeRightsManagementSessionHandle.cs
- OleDbEnumerator.cs
- FileLogRecord.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- UnauthorizedWebPart.cs
- Style.cs
- SmiContext.cs
- UrlParameterReader.cs
- OledbConnectionStringbuilder.cs
- ExpressionConverter.cs
- TypeConverterHelper.cs
- DashStyles.cs
- RegionData.cs
- BamlTreeUpdater.cs
- EndpointAddressElementBase.cs
- PrintPreviewDialog.cs
- UpdateProgress.cs
- ByteAnimation.cs
- DecoderExceptionFallback.cs
- SqlClientWrapperSmiStream.cs
- FileDetails.cs
- GridItemPattern.cs
- SuspendDesigner.cs
- LogExtentCollection.cs
- BaseTemplateCodeDomTreeGenerator.cs
- Int32EqualityComparer.cs
- DesignerTransaction.cs
- Merger.cs
- QilScopedVisitor.cs
- TransformConverter.cs
- DateTimeValueSerializerContext.cs
- ComboBoxItem.cs
- ToolboxItem.cs
- BamlStream.cs
- ToolStripPanelRow.cs
- SafeLocalMemHandle.cs
- BeginEvent.cs
- BlurBitmapEffect.cs
- OleAutBinder.cs
- PlatformCulture.cs
- InputQueueChannelAcceptor.cs
- ThrowHelper.cs
- _ListenerResponseStream.cs
- PriorityBindingExpression.cs
- UserControlAutomationPeer.cs
- HostExecutionContextManager.cs
- wmiprovider.cs
- SynchronizedMessageSource.cs
- TiffBitmapEncoder.cs
- ConsumerConnectionPoint.cs
- WebPartConnectionsConfigureVerb.cs
- BuilderInfo.cs
- TypeDescriptor.cs
- TdsParserStateObject.cs
- IndependentAnimationStorage.cs
- _NegoStream.cs
- ParagraphVisual.cs
- VirtualPath.cs
- EntityDataSourceView.cs
- IsolatedStorageSecurityState.cs
- cookie.cs
- EditorPartChrome.cs
- WhitespaceRuleReader.cs
- XomlCompilerError.cs
- ColumnPropertiesGroup.cs
- VerticalAlignConverter.cs
- InputManager.cs
- SafeHGlobalHandleCritical.cs
- XamlReader.cs
- CodeGenerator.cs
- ADMembershipProvider.cs
- RequestCache.cs
- OracleConnectionString.cs
- Positioning.cs
- PaintValueEventArgs.cs
- AnonymousIdentificationModule.cs
- ContractTypeNameCollection.cs
- ServiceNotStartedException.cs
- DataGridViewCellStateChangedEventArgs.cs
- SystemIcmpV6Statistics.cs
- Viewport3DAutomationPeer.cs
- DateTimeOffset.cs