Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / Annotations / XmlElementCollection.cs / 1 / XmlElementCollection.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) 2003 by Microsoft Corporation. All rights reserved.
//
//
//
// Description: Subclass of ObservableCollection which also registers for
// change notifications from the XmlElements it contains. It fires
// CollectionChanged event with action==Reset for any item that
// changed. This is sufficient to let owner objects know an item
// has changed.
//
// History:
// 03/10/2005 : rruiz - created
//
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Xml;
using MS.Internal;
namespace MS.Internal.Annotations
{
///
///
internal sealed class XmlElementCollection : ObservableCollection
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Initializes a new instance of XmlElementCollection that is empty and has default initial capacity.
///
public XmlElementCollection() : base()
{
_xmlDocsRefCounts = new Dictionary();
}
#endregion Constructors
//------------------------------------------------------
//
// Public Events
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Protected Methods
//
//------------------------------------------------------
#region Protected Methods
///
/// called by base class Collection<T> when the list is being cleared;
/// unregisters from all items
///
protected override void ClearItems()
{
foreach (XmlElement item in this)
{
UnregisterForElement(item);
}
base.ClearItems();
}
///
/// called by base class Collection<T> when an item is removed from list;
/// unregisters on item being removed
///
protected override void RemoveItem(int index)
{
XmlElement removedItem = this[index];
UnregisterForElement(removedItem);
base.RemoveItem(index);
}
///
/// called by base class Collection<T> when an item is added to list;
/// registers on new item
///
protected override void InsertItem(int index, XmlElement item)
{
if (item != null && this.Contains(item))
{
throw new ArgumentException(SR.Get(SRID.XmlNodeAlreadyOwned, "change", "change"), "item");
}
base.InsertItem(index, item);
RegisterForElement(item);
}
///
/// called by base class Collection<T> when an item is added to list;
/// unregisters on previous item and registers for new item
///
protected override void SetItem(int index, XmlElement item)
{
if (item != null && this.Contains(item))
{
throw new ArgumentException(SR.Get(SRID.XmlNodeAlreadyOwned, "change", "change"), "item");
}
XmlElement originalItem = this[index];
UnregisterForElement(originalItem);
Items[index] = item; // directly set Collection inner Items collection
OnCollectionReset();
RegisterForElement(item);
}
#endregion Protected Methods
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// Unregister for change notifications for this element.
/// We decrease the reference count and unregister if the count
/// has reached zero.
///
/// the element to unregister for
private void UnregisterForElement(XmlElement element)
{
// Nulls may exist in the collection in which case we don't need to unregister
if (element == null)
return;
Invariant.Assert(_xmlDocsRefCounts.ContainsKey(element.OwnerDocument), "Not registered on XmlElement");
// Decrease the reference count
_xmlDocsRefCounts[element.OwnerDocument]--;
// If the reference count is at zero, we can unregister for notifications
// from the document and clear out its entry in the hashtable.
if (_xmlDocsRefCounts[element.OwnerDocument] == 0)
{
element.OwnerDocument.NodeChanged -= OnNodeChanged;
element.OwnerDocument.NodeInserted -= OnNodeChanged;
element.OwnerDocument.NodeRemoved -= OnNodeChanged;
_xmlDocsRefCounts.Remove(element.OwnerDocument);
}
}
///
/// Register for change notifications for this element. In
/// reality we regiser on the OwnerDocument, so we keep a count
/// of all the elements from a particular docuemnt we are listening
/// for. If that ref count gets to zero we unregister from the
/// document.
///
/// the element to register for
private void RegisterForElement(XmlElement element)
{
// Nulls may exist in the collection in which case we don't need to register
if (element == null)
return;
if (!_xmlDocsRefCounts.ContainsKey(element.OwnerDocument))
{
// If we aren't register on this document yet, register
// and initialize the reference count to 1.
_xmlDocsRefCounts[element.OwnerDocument] = 1;
XmlNodeChangedEventHandler handler = new XmlNodeChangedEventHandler(OnNodeChanged);
element.OwnerDocument.NodeChanged += handler;
element.OwnerDocument.NodeInserted += handler;
element.OwnerDocument.NodeRemoved += handler;
}
else
{
// Increase the reference count
_xmlDocsRefCounts[element.OwnerDocument]++;
}
}
///
/// We register for node changes on the documents that own the contents
/// of this Resource. Its the only way to know if the contents have
/// changed.
///
/// document whose node has changed
/// args describing the kind of change and specifying the node that changed
private void OnNodeChanged(object sender, XmlNodeChangedEventArgs args)
{
XmlAttribute attr = null;
XmlElement element = null;
// We should only be getting notifications from documents we have registered on
Invariant.Assert(_xmlDocsRefCounts.ContainsKey(sender as XmlDocument), "Not expecting a notification from this sender");
// The node that changed may not be a content but could be a part of a content
// (such as an attribute node). Therefore we must walk up from the node until
// we either a) get to the root or b) find a content we contain. In the case of
// (a) we do nothing. In the case of (b) we must fire a change notification
// for this Resource.
XmlNode current = args.Node;
while (current != null)
{
element = current as XmlElement;
if (element != null && this.Contains(element))
{
OnCollectionReset();
break;
}
// Get the parent of the current node
attr = current as XmlAttribute;
if (attr != null)
{
// ParentNode isn't implemented for XmlAttributes, we must
// use its OwnerElement to continue our walk up the node tree.
current = attr.OwnerElement;
}
else
{
current = current.ParentNode;
}
}
}
private void OnCollectionReset()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
Dictionary _xmlDocsRefCounts;
#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: Subclass of ObservableCollection which also registers for
// change notifications from the XmlElements it contains. It fires
// CollectionChanged event with action==Reset for any item that
// changed. This is sufficient to let owner objects know an item
// has changed.
//
// History:
// 03/10/2005 : rruiz - created
//
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Xml;
using MS.Internal;
namespace MS.Internal.Annotations
{
///
///
internal sealed class XmlElementCollection : ObservableCollection
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Initializes a new instance of XmlElementCollection that is empty and has default initial capacity.
///
public XmlElementCollection() : base()
{
_xmlDocsRefCounts = new Dictionary();
}
#endregion Constructors
//------------------------------------------------------
//
// Public Events
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Protected Methods
//
//------------------------------------------------------
#region Protected Methods
///
/// called by base class Collection<T> when the list is being cleared;
/// unregisters from all items
///
protected override void ClearItems()
{
foreach (XmlElement item in this)
{
UnregisterForElement(item);
}
base.ClearItems();
}
///
/// called by base class Collection<T> when an item is removed from list;
/// unregisters on item being removed
///
protected override void RemoveItem(int index)
{
XmlElement removedItem = this[index];
UnregisterForElement(removedItem);
base.RemoveItem(index);
}
///
/// called by base class Collection<T> when an item is added to list;
/// registers on new item
///
protected override void InsertItem(int index, XmlElement item)
{
if (item != null && this.Contains(item))
{
throw new ArgumentException(SR.Get(SRID.XmlNodeAlreadyOwned, "change", "change"), "item");
}
base.InsertItem(index, item);
RegisterForElement(item);
}
///
/// called by base class Collection<T> when an item is added to list;
/// unregisters on previous item and registers for new item
///
protected override void SetItem(int index, XmlElement item)
{
if (item != null && this.Contains(item))
{
throw new ArgumentException(SR.Get(SRID.XmlNodeAlreadyOwned, "change", "change"), "item");
}
XmlElement originalItem = this[index];
UnregisterForElement(originalItem);
Items[index] = item; // directly set Collection inner Items collection
OnCollectionReset();
RegisterForElement(item);
}
#endregion Protected Methods
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
///
/// Unregister for change notifications for this element.
/// We decrease the reference count and unregister if the count
/// has reached zero.
///
/// the element to unregister for
private void UnregisterForElement(XmlElement element)
{
// Nulls may exist in the collection in which case we don't need to unregister
if (element == null)
return;
Invariant.Assert(_xmlDocsRefCounts.ContainsKey(element.OwnerDocument), "Not registered on XmlElement");
// Decrease the reference count
_xmlDocsRefCounts[element.OwnerDocument]--;
// If the reference count is at zero, we can unregister for notifications
// from the document and clear out its entry in the hashtable.
if (_xmlDocsRefCounts[element.OwnerDocument] == 0)
{
element.OwnerDocument.NodeChanged -= OnNodeChanged;
element.OwnerDocument.NodeInserted -= OnNodeChanged;
element.OwnerDocument.NodeRemoved -= OnNodeChanged;
_xmlDocsRefCounts.Remove(element.OwnerDocument);
}
}
///
/// Register for change notifications for this element. In
/// reality we regiser on the OwnerDocument, so we keep a count
/// of all the elements from a particular docuemnt we are listening
/// for. If that ref count gets to zero we unregister from the
/// document.
///
/// the element to register for
private void RegisterForElement(XmlElement element)
{
// Nulls may exist in the collection in which case we don't need to register
if (element == null)
return;
if (!_xmlDocsRefCounts.ContainsKey(element.OwnerDocument))
{
// If we aren't register on this document yet, register
// and initialize the reference count to 1.
_xmlDocsRefCounts[element.OwnerDocument] = 1;
XmlNodeChangedEventHandler handler = new XmlNodeChangedEventHandler(OnNodeChanged);
element.OwnerDocument.NodeChanged += handler;
element.OwnerDocument.NodeInserted += handler;
element.OwnerDocument.NodeRemoved += handler;
}
else
{
// Increase the reference count
_xmlDocsRefCounts[element.OwnerDocument]++;
}
}
///
/// We register for node changes on the documents that own the contents
/// of this Resource. Its the only way to know if the contents have
/// changed.
///
/// document whose node has changed
/// args describing the kind of change and specifying the node that changed
private void OnNodeChanged(object sender, XmlNodeChangedEventArgs args)
{
XmlAttribute attr = null;
XmlElement element = null;
// We should only be getting notifications from documents we have registered on
Invariant.Assert(_xmlDocsRefCounts.ContainsKey(sender as XmlDocument), "Not expecting a notification from this sender");
// The node that changed may not be a content but could be a part of a content
// (such as an attribute node). Therefore we must walk up from the node until
// we either a) get to the root or b) find a content we contain. In the case of
// (a) we do nothing. In the case of (b) we must fire a change notification
// for this Resource.
XmlNode current = args.Node;
while (current != null)
{
element = current as XmlElement;
if (element != null && this.Contains(element))
{
OnCollectionReset();
break;
}
// Get the parent of the current node
attr = current as XmlAttribute;
if (attr != null)
{
// ParentNode isn't implemented for XmlAttributes, we must
// use its OwnerElement to continue our walk up the node tree.
current = attr.OwnerElement;
}
else
{
current = current.ParentNode;
}
}
}
private void OnCollectionReset()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
#endregion Private Methods
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
Dictionary _xmlDocsRefCounts;
#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
- OutputCacheProviderCollection.cs
- itemelement.cs
- ObjectReaderCompiler.cs
- assertwrapper.cs
- XmlNodeChangedEventArgs.cs
- ToolStripManager.cs
- XNodeNavigator.cs
- RawTextInputReport.cs
- LicenseProviderAttribute.cs
- FormParameter.cs
- NetworkStream.cs
- RegexBoyerMoore.cs
- CacheMode.cs
- StyleXamlParser.cs
- LiteralControl.cs
- AspCompat.cs
- DBCSCodePageEncoding.cs
- MDIClient.cs
- PieceNameHelper.cs
- FontWeight.cs
- LZCodec.cs
- PaintValueEventArgs.cs
- X509PeerCertificateElement.cs
- CharUnicodeInfo.cs
- HttpRawResponse.cs
- KeyEvent.cs
- ObjectViewFactory.cs
- HttpCapabilitiesBase.cs
- TemplateControl.cs
- ListViewInsertionMark.cs
- FieldBuilder.cs
- PriorityQueue.cs
- RTLAwareMessageBox.cs
- ComponentResourceKey.cs
- RequestCachePolicyConverter.cs
- BuildProvider.cs
- Propagator.cs
- MailSettingsSection.cs
- _BufferOffsetSize.cs
- FullTextBreakpoint.cs
- QuaternionRotation3D.cs
- WaitHandleCannotBeOpenedException.cs
- TextSerializer.cs
- InternalBufferOverflowException.cs
- CultureTable.cs
- WbmpConverter.cs
- SafeRegistryHandle.cs
- WindowsRegion.cs
- MDIClient.cs
- MediaTimeline.cs
- EventLevel.cs
- PerformanceCounter.cs
- SHA1CryptoServiceProvider.cs
- TrustLevelCollection.cs
- SoapAttributes.cs
- BamlWriter.cs
- MaterialCollection.cs
- MdiWindowListStrip.cs
- PingOptions.cs
- ProcessInfo.cs
- ScopeElement.cs
- SignatureTargetIdManager.cs
- DocumentProperties.cs
- PropertyChangeTracker.cs
- OperandQuery.cs
- XmlUTF8TextWriter.cs
- Events.cs
- Column.cs
- CommonGetThemePartSize.cs
- IPEndPoint.cs
- SqlDataSourceSelectingEventArgs.cs
- HtmlSelect.cs
- TemplateBaseAction.cs
- WebServicesSection.cs
- HttpValueCollection.cs
- SecurityPolicySection.cs
- MultiPropertyDescriptorGridEntry.cs
- TransactionsSectionGroup.cs
- KeyTime.cs
- HttpResponseBase.cs
- TdsParameterSetter.cs
- XsltContext.cs
- NullableFloatMinMaxAggregationOperator.cs
- _IPv6Address.cs
- WhileDesigner.cs
- WinOEToolBoxItem.cs
- StreamUpdate.cs
- BitmapEffectInput.cs
- objectquery_tresulttype.cs
- QueryResponse.cs
- ObfuscateAssemblyAttribute.cs
- CheckBoxAutomationPeer.cs
- BuildProvider.cs
- HierarchicalDataSourceDesigner.cs
- ReversePositionQuery.cs
- CompareValidator.cs
- PreProcessInputEventArgs.cs
- DetailsViewPageEventArgs.cs
- SmtpTransport.cs
- ZipPackage.cs