Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media3D / Visual3DCollection.cs / 1305600 / Visual3DCollection.cs
//----------------------------------------------------------------------------
//
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// History:
// 6/9/2005 : [....] - Created
//
//---------------------------------------------------------------------------
#pragma warning disable 1634, 1691 // suppressing PreSharp warnings
using MS.Utility;
using MS.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using MS.Internal.PresentationCore;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.Media3D
{
///
/// A collection of Visual3D objects.
///
public sealed class Visual3DCollection : IList, IList
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
internal Visual3DCollection(IVisual3DContainer owner)
{
_owner = owner;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
///
/// Adds the value to the collection.
///
public void Add(Visual3D value)
{
VerifyAPIForAdd(value);
int addedPosition = InternalCount;
_collection.Add(value);
InvalidateEnumerators();
// NOTE: The collection must be updated before notifying the Visual.
ConnectChild(addedPosition, value);
Debug_ICC();
}
private void ConnectChild(int index, Visual3D value)
{
value.ParentIndex = index;
_owner.AddChild(value);
}
///
/// Inserts the value into the list at the specified position
///
public void Insert(int index, Visual3D value)
{
VerifyAPIForAdd(value);
InternalInsert(index, value);
}
///
/// Removes the value from the collection.
///
public bool Remove(Visual3D value)
{
VerifyAPIReadWrite(value);
if (!_collection.Contains(value))
{
return false;
}
InternalRemoveAt(value.ParentIndex);
return true;
}
///
/// Removes the value at the specified index.
///
public void RemoveAt(int index)
{
if (index < 0 || index >= InternalCount)
{
throw new ArgumentOutOfRangeException("index");
}
VerifyAPIReadWrite(_collection[index]);
InternalRemoveAt(index);
}
///
/// Removes all IElements from the collection.
///
public void Clear()
{
VerifyAPIReadWrite();
// Rather than clear, we swap out the FrugalStructList because
// we need to keep the old values around to notify the parent
// they were removed.
FrugalStructList oldCollection = _collection;
_collection = new FrugalStructList();
InvalidateEnumerators();
// NOTE: The collection must be updated before notifying the Visual.
for (int i = oldCollection.Count - 1; i >= 0; i--)
{
_owner.RemoveChild(oldCollection[i]);
}
Debug_ICC();
}
///
/// Copies the IElements of the collection into "array" starting at "index"
///
public void CopyTo(Visual3D[] array, int index)
{
VerifyAPIReadOnly();
if (array == null)
{
throw new ArgumentNullException("array");
}
// The extra "index >= array.Length" check in because even if _collection.Count
// is 0 the index is not allowed to be equal or greater than the length
// (from the MSDN ICollection docs)
if (index < 0 || index >= array.Length || (index + _collection.Count) > array.Length)
{
throw new ArgumentOutOfRangeException("index");
}
_collection.CopyTo(array, index);
}
void ICollection.CopyTo(Array array, int index)
{
VerifyAPIReadOnly();
if (array == null)
{
throw new ArgumentNullException("array");
}
// The extra "index >= array.Length" check in because even if _collection.Count
// is 0 the index is not allowed to be equal or greater than the length
// (from the MSDN ICollection docs)
if (index < 0 || index >= array.Length || (index + _collection.Count) > array.Length)
{
throw new ArgumentOutOfRangeException("index");
}
if (array.Rank != 1)
{
throw new ArgumentException(SR.Get(SRID.Collection_BadRank));
}
// Elsewhere in the collection we throw an AE when the type is
// bad so we do it here as well to be consistent
try
{
int count = _collection.Count;
for (int i = 0; i < count; i++)
{
array.SetValue(_collection[i], index + i);
}
}
catch (InvalidCastException e)
{
throw new ArgumentException(SR.Get(SRID.Collection_BadDestArray, "Visual3DCollection"), e);
}
}
///
/// Determines if the list contains "value"
///
public bool Contains(Visual3D value)
{
VerifyAPIReadOnly(value);
return (value != null && (value.InternalVisualParent == _owner));
}
///
/// Returns the index of value in the list
///
public int IndexOf(Visual3D value)
{
VerifyAPIReadOnly(value);
if (value == null || (value.InternalVisualParent != _owner))
{
return -1;
}
#pragma warning disable 56506 // Suppress presharp warning: Parameter 'value' to this public method must be validated: A null-dereference can occur here.
return value.ParentIndex;
#pragma warning restore 56506
}
///
/// Returns an Enumerator for the collection.
///
public Enumerator GetEnumerator()
{
VerifyAPIReadOnly();
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// Returns the IElement at the given index in the collection.
///
public Visual3D this[int index]
{
get
{
VerifyAPIReadOnly();
return InternalGetItem(index);
}
set
{
if (index < 0 || index >= InternalCount)
{
throw new ArgumentOutOfRangeException("index");
}
VerifyAPIForAdd(value);
InternalRemoveAt(index);
InternalInsert(index, value);
}
}
///
/// The number of IElements contained in the collection.
///
public int Count
{
get
{
VerifyAPIReadOnly();
return InternalCount;
}
}
bool ICollection.IsSynchronized
{
get
{
VerifyAPIReadOnly();
// True because we force single thread access via VerifyAccess()
return true;
}
}
object ICollection.SyncRoot
{
get
{
VerifyAPIReadOnly();
return _owner;
}
}
bool ICollection.IsReadOnly
{
get
{
VerifyAPIReadOnly();
return false;
}
}
#region IList Members
///
/// Adds an element to the Visual3DCollection
///
int IList.Add(object value)
{
Add(Cast(value));
return InternalCount - 1;
}
///
/// Determines whether an element is in the Visual3DCollection.
///
bool IList.Contains(object value)
{
return Contains(value as Visual3D);
}
///
/// Returns the index of the element in the Visual3DCollection
///
int IList.IndexOf(object value)
{
return IndexOf(value as Visual3D);
}
///
/// Inserts an element into the Visual3DCollection
///
void IList.Insert(int index, object value)
{
Insert(index, Cast(value));
}
///
///
bool IList.IsFixedSize
{
get { return false; }
}
///
///
bool IList.IsReadOnly
{
get { return false; }
}
///
/// Removes an element from the Visual3DCollection
///
void IList.Remove(object value)
{
Remove(value as Visual3D);
}
///
/// For more details, see
///
object IList.this[int index]
{
get
{
return this[index];
}
set
{
this[index] = Cast(value);
}
}
#endregion
#endregion Public Properties
//-----------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal Visual3D InternalGetItem(int index)
{
return _collection[index];
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
internal int InternalCount
{
get { return _collection.Count; }
}
#endregion Internal Properties
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
private void VerifyAPIReadOnly()
{
Debug_ICC();
_owner.VerifyAPIReadOnly();
}
private void VerifyAPIReadOnly(Visual3D other)
{
Debug_ICC();
_owner.VerifyAPIReadOnly(other);
}
private void VerifyAPIReadWrite()
{
Debug_ICC();
_owner.VerifyAPIReadWrite();
}
private void VerifyAPIReadWrite(Visual3D other)
{
Debug_ICC();
_owner.VerifyAPIReadWrite(other);
}
private Visual3D Cast(object value)
{
if( value == null )
{
throw new System.ArgumentNullException("value");
}
if (!(value is Visual3D))
{
throw new System.ArgumentException(SR.Get(SRID.Collection_BadType, this.GetType().Name, value.GetType().Name, "Visual3D"));
}
return (Visual3D) value;
}
private void VerifyAPIForAdd(Visual3D value)
{
if (value == null)
{
throw new System.ArgumentException(SR.Get(SRID.Collection_NoNull));
}
VerifyAPIReadWrite(value);
if (value.InternalVisualParent != null)
{
throw new System.ArgumentException(SR.Get(SRID.VisualCollection_VisualHasParent));
}
}
private void InternalInsert(int index, Visual3D value)
{
_collection.Insert(index, value);
// Update ParentIndex value on each Visual3D. Run through them
// and increment. Note that this means that Inserting/Removal from a
// Visual3DCollection can be O(n^2) if done in the wrong order.
for (int i = index + 1, count = InternalCount; i < count; i++)
{
Debug.Assert(InternalGetItem(i).ParentIndex == i - 1,
"ParentIndex has been corrupted.");
InternalGetItem(i).ParentIndex = i;
}
InvalidateEnumerators();
// NOTE: The collection must be updated before notifying the Visual.
ConnectChild(index, value);
Debug_ICC();
}
private void InternalRemoveAt(int index)
{
Visual3D value = _collection[index];
_collection.RemoveAt(index);
// Update ParentIndices after the modified index are now invalid. Run through them
// and decrement. Note that this means that Inserting/Removal from a
// Visual3DCollection can be O(n^2) if done in the wrong order.
for (int i = index; i < InternalCount; i++)
{
Debug.Assert(InternalGetItem(i).ParentIndex == i + 1,
"ParentIndex has been corrupted.");
InternalGetItem(i).ParentIndex = i;
}
InvalidateEnumerators();
// NOTE: The collection must be updated before notifying the Visual.
_owner.RemoveChild(value);
Debug_ICC();
}
// Each member which modifies the collection should call this method to
// invalidate any enumerators which might have been handed out.
private void InvalidateEnumerators()
{
_version++;
}
#endregion Private Methods
//------------------------------------------------------
//
// DEBUG
//
//-----------------------------------------------------
#region DEBUG
[Conditional("DEBUG")]
private void Debug_ICC()
{
Debug.Assert(_owner != null, "How did an Visual3DCollection get constructed without an owner?");
Dictionary duplicates = new Dictionary();
for (int i = 0; i < _collection.Count; i++)
{
Visual3D visual = _collection[i];
Debug.Assert(!duplicates.ContainsKey(visual), "How did the visual get re-inserted?");
duplicates.Add(visual, String.Empty);
Debug.Assert(visual.InternalVisualParent == _owner, "Why isn't our child's parent pointer the same as the collection owner?");
Debug.Assert(visual.ParentIndex == i,
String.Format(
CultureInfo.InvariantCulture,
"Child's ParentIndex does not match the child's actual position in the collection. Expected='{0}' Actual='{1}'",
i,
visual.ParentIndex));
// If the Visual3D is being added to the collection via a resource reference
// its inheritance context will be the owner of the ResourceDictionary in which
// it was declared. (For more info, see Windows OS Bugs #1614016)
//
// Debug.Assert(visual.InheritanceContext == _inheritanceContext,
// "How did a Visual3D get inserted without updating it's InheritanceContext?");
}
}
#endregion DEBUG
//------------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
private IVisual3DContainer _owner = null;
private FrugalStructList _collection = new FrugalStructList();
private int _version = 0;
#endregion Private Fields
//-----------------------------------------------------
//
// Enumerator
//
//-----------------------------------------------------
#region Enumerator
///
/// VisualCollection Enumerator.
///
public struct Enumerator : IEnumerator, IEnumerator
{
#region Constructors
internal Enumerator(Visual3DCollection list)
{
Debug.Assert(list != null, "list may not be null.");
_list = list;
_index = -1;
_version = _list._version;
}
#endregion Constructors
#region Public Methods
///
/// Advances the enumerator to the next IElement of the collection.
///
public bool MoveNext()
{
if (_list._version != _version)
{
throw new InvalidOperationException(SR.Get(SRID.Enumerator_CollectionChanged));
}
int count = _list.Count;
if (_index < count)
{
_index++;
}
return _index < count;
}
///
/// Resets the enumerator to its initial position.
///
public void Reset()
{
if (_list._version != _version)
{
throw new InvalidOperationException(SR.Get(SRID.Enumerator_CollectionChanged));
}
_index = -1;
}
void IDisposable.Dispose()
{
// Do nothing - Required by the IEnumeable contract.
}
#endregion Public Methods
#region Public Properties
object IEnumerator.Current
{
get
{
return this.Current;
}
}
///
/// Returns the current IElement.
///
public Visual3D Current
{
#pragma warning disable 1634, 1691
#pragma warning disable 6503
get
{
if ((_index < 0) || (_index >= _list.Count))
{
throw new InvalidOperationException(SR.Get(SRID.Enumerator_VerifyContext));
}
return _list[_index];
}
#pragma warning restore 6503
#pragma warning restore 1634, 1691
}
#endregion Public Methods
#region Private Fields
private Visual3DCollection _list;
private int _index;
private int _version;
#endregion Private Fields
}
#endregion Enumerator
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ContextMenu.cs
- Decorator.cs
- AnimatedTypeHelpers.cs
- SessionStateModule.cs
- StreamInfo.cs
- XPathExpr.cs
- WebSysDefaultValueAttribute.cs
- ClientScriptItemCollection.cs
- SafeSecurityHandles.cs
- ToolstripProfessionalRenderer.cs
- NavigationProperty.cs
- MachineSettingsSection.cs
- CodeNamespaceImport.cs
- GatewayDefinition.cs
- CommandManager.cs
- ErrorInfoXmlDocument.cs
- DataGridViewTopRowAccessibleObject.cs
- PrintingPermissionAttribute.cs
- DrawingVisualDrawingContext.cs
- EntityDataSourceEntitySetNameItem.cs
- EventProperty.cs
- ContextDataSourceView.cs
- MergeEnumerator.cs
- XmlAttributeCollection.cs
- Span.cs
- Cell.cs
- CallTemplateAction.cs
- FontFamily.cs
- SQLBoolean.cs
- SystemWebExtensionsSectionGroup.cs
- LinkedResourceCollection.cs
- ThicknessKeyFrameCollection.cs
- Accessible.cs
- ObsoleteAttribute.cs
- Publisher.cs
- BaseParser.cs
- StringKeyFrameCollection.cs
- ConnectionInterfaceCollection.cs
- ElementMarkupObject.cs
- DesignerWebPartChrome.cs
- WpfXamlLoader.cs
- BigIntegerStorage.cs
- Decimal.cs
- BooleanAnimationBase.cs
- DrawingAttributeSerializer.cs
- SchemaSetCompiler.cs
- HttpApplicationFactory.cs
- ISessionStateStore.cs
- HandlerBase.cs
- DataErrorValidationRule.cs
- DBSqlParserColumn.cs
- DataSourceSelectArguments.cs
- XPathNodeList.cs
- XmlSchemaObject.cs
- ListViewGroupItemCollection.cs
- RegistryConfigurationProvider.cs
- AlgoModule.cs
- DataExchangeServiceBinder.cs
- XmlSchemaSimpleContentExtension.cs
- StreamSecurityUpgradeAcceptorBase.cs
- XhtmlBasicLinkAdapter.cs
- DESCryptoServiceProvider.cs
- x509utils.cs
- DrawingBrush.cs
- Event.cs
- UrlPath.cs
- VectorKeyFrameCollection.cs
- XmlSchemaInferenceException.cs
- DesignerGenericWebPart.cs
- XmlAggregates.cs
- SetState.cs
- IndentedWriter.cs
- DataObjectMethodAttribute.cs
- ScopelessEnumAttribute.cs
- ClosureBinding.cs
- SqlDataSource.cs
- Delay.cs
- TreeViewCancelEvent.cs
- WhitespaceRuleLookup.cs
- Adorner.cs
- ThreadStartException.cs
- RuleSettingsCollection.cs
- ShutDownListener.cs
- InputReport.cs
- InvalidWMPVersionException.cs
- FieldToken.cs
- ComponentEvent.cs
- KeyValueConfigurationCollection.cs
- FSWPathEditor.cs
- APCustomTypeDescriptor.cs
- HtmlTableRow.cs
- CacheEntry.cs
- Splitter.cs
- TextSpan.cs
- WebBrowserNavigatingEventHandler.cs
- Avt.cs
- IsolatedStorageException.cs
- Configuration.cs
- EndpointNameMessageFilter.cs
- ReflectionUtil.cs