Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / Host / ReferenceService.cs / 1 / ReferenceService.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.ComponentModel.Design {
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Globalization;
///
/// This service allows clients to work with all references on a form, not just
/// the top-level sited components.
///
internal sealed class ReferenceService : IReferenceService, IDisposable {
private static readonly Attribute[] _attributes = new Attribute[] {DesignerSerializationVisibilityAttribute.Content};
private IServiceProvider _provider; // service provider we use to get to other services
private ArrayList _addedComponents; // list of newly added components
private ArrayList _removedComponents; // list of newly removed components
private ArrayList _references; // our current list of references
private bool _populating;
///
/// Constructs the ReferenceService.
///
internal ReferenceService(IServiceProvider provider) {
_provider = provider;
}
///
/// Creates an entry for a top-level component and it's children.
///
private void CreateReferences(IComponent component) {
CreateReferences(string.Empty, component, component);
}
///
/// Recursively creates references for namespaced objects.
///
private void CreateReferences(string trailingName, object reference, IComponent sitedComponent) {
if (object.ReferenceEquals(reference, null)) {
return;
}
_references.Add(new ReferenceHolder(trailingName, reference, sitedComponent));
foreach(PropertyDescriptor property in TypeDescriptor.GetProperties(reference, _attributes)) {
if (property.IsReadOnly) {
CreateReferences(
string.Format(CultureInfo.CurrentCulture, "{0}.{1}", trailingName, property.Name),
property.GetValue(reference),
sitedComponent);
}
}
}
///
/// Demand populates the _references variable.
///
private void EnsureReferences() {
// If the references are null, create them for the first time and connect
// up our events to listen to changes to the container. Otherwise, check to
// see if the added or removed lists contain anything for us to sync up.
//
if (_references == null) {
if (_provider == null) {
throw new ObjectDisposedException("IReferenceService");
}
IComponentChangeService cs = _provider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
Debug.Assert(cs != null, "Reference service relies on IComponentChangeService");
if (cs != null) {
cs.ComponentAdded += new ComponentEventHandler(this.OnComponentAdded);
cs.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved);
cs.ComponentRename += new ComponentRenameEventHandler(this.OnComponentRename);
}
IContainer container = _provider.GetService(typeof(IContainer)) as IContainer;
if (container == null) {
Debug.Fail("Reference service cannot operate without IContainer");
throw new InvalidOperationException();
}
_references = new ArrayList(container.Components.Count);
foreach(IComponent component in container.Components) {
CreateReferences(component);
}
}
else if (!_populating) {
_populating = true;
try {
if (_addedComponents != null && _addedComponents.Count > 0) {
// There is a possibility that this component already exists.
// If it does, just remove it first and then re-add it.
//
foreach (IComponent ic in _addedComponents) {
RemoveReferences(ic);
CreateReferences(ic);
}
_addedComponents.Clear();
}
if (_removedComponents != null && _removedComponents.Count > 0) {
foreach (IComponent ic in _removedComponents) {
RemoveReferences(ic);
}
_removedComponents.Clear();
}
}
finally {
_populating = false;
}
}
}
///
/// Listens for component additions to find all the references it contributes.
///
private void OnComponentAdded(object sender, ComponentEventArgs cevent) {
if (_addedComponents == null) {
_addedComponents = new ArrayList();
}
IComponent compAdded = cevent.Component;
if (!(compAdded.Site is INestedSite))
{
_addedComponents.Add(compAdded);
if (_removedComponents != null) {
_removedComponents.Remove(compAdded);
}
}
}
///
/// Listens for component removes to delete all the references it holds.
///
private void OnComponentRemoved(object sender, ComponentEventArgs cevent) {
if (_removedComponents == null) {
_removedComponents = new ArrayList();
}
IComponent compRemoved = cevent.Component;
if (!(compRemoved.Site is INestedSite))
{
_removedComponents.Add(compRemoved);
if (_addedComponents != null) {
_addedComponents.Remove(compRemoved);
}
}
}
///
/// Listens for component removes to delete all the references it holds.
///
private void OnComponentRename(object sender, ComponentRenameEventArgs cevent) {
foreach (ReferenceHolder reference in _references) {
if (object.ReferenceEquals(reference.SitedComponent, cevent.Component)) {
reference.ResetName();
return;
}
}
}
///
/// Removes all the references that this component owns.
///
private void RemoveReferences(IComponent component) {
if (_references != null) {
int size = _references.Count;
for (int i = size - 1; i >= 0; i--) {
if (object.ReferenceEquals(((ReferenceHolder)_references[i]).SitedComponent, component)) {
_references.RemoveAt(i);
}
}
}
}
///
/// Cleanup and detach from our events.
///
void IDisposable.Dispose() {
if (_references != null && _provider != null) {
IComponentChangeService cs = _provider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if (cs != null) {
cs.ComponentAdded -= new ComponentEventHandler(this.OnComponentAdded);
cs.ComponentRemoved -= new ComponentEventHandler(this.OnComponentRemoved);
cs.ComponentRename -= new ComponentRenameEventHandler(this.OnComponentRename);
}
_references = null;
_provider = null;
}
}
///
/// Finds the sited component for a given reference, returning null if not found.
///
IComponent IReferenceService.GetComponent(object reference) {
if (object.ReferenceEquals(reference, null)) {
throw new ArgumentNullException("reference");
}
EnsureReferences();
foreach(ReferenceHolder holder in _references) {
if (object.ReferenceEquals(holder.Reference, reference)) {
return holder.SitedComponent;
}
}
return null;
}
///
/// Finds name for a given reference, returning null if not found.
///
string IReferenceService.GetName(object reference) {
if (object.ReferenceEquals(reference, null)) {
throw new ArgumentNullException("reference");
}
EnsureReferences();
foreach(ReferenceHolder holder in _references) {
if (object.ReferenceEquals(holder.Reference, reference)) {
return holder.Name;
}
}
return null;
}
///
/// Finds a reference with the given name, returning null if not found.
///
object IReferenceService.GetReference(string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
EnsureReferences();
foreach(ReferenceHolder holder in _references) {
if (string.Equals(holder.Name, name, StringComparison.OrdinalIgnoreCase)) {
return holder.Reference;
}
}
return null;
}
///
/// Returns all references available in this designer.
///
object[] IReferenceService.GetReferences() {
EnsureReferences();
object[] references = new object[_references.Count];
for(int i = 0; i < references.Length; i++) {
references[i] = ((ReferenceHolder)_references[i]).Reference;
}
return references;
}
///
/// Returns all references available in this designer that are assignable to the given type.
///
object[] IReferenceService.GetReferences(Type baseType) {
if (baseType == null) {
throw new ArgumentNullException("baseType");
}
EnsureReferences();
ArrayList results = new ArrayList(_references.Count);
foreach(ReferenceHolder holder in _references) {
object reference = holder.Reference;
if (baseType.IsAssignableFrom(reference.GetType())) {
results.Add(reference);
}
}
object[] references = new object[results.Count];
results.CopyTo(references, 0);
return references;
}
///
/// The class that holds the information about a reference.
///
private sealed class ReferenceHolder {
private string _trailingName;
private object _reference;
private IComponent _sitedComponent;
private string _fullName;
///
/// Creates a new reference holder.
///
internal ReferenceHolder(string trailingName, object reference, IComponent sitedComponent) {
_trailingName = trailingName;
_reference = reference;
_sitedComponent = sitedComponent;
Debug.Assert(trailingName != null, "Expected a trailing name");
Debug.Assert(reference != null, "Expected a reference");
#if DEBUG
Debug.Assert(sitedComponent != null, "Expected a sited component");
if (sitedComponent != null) Debug.Assert(sitedComponent.Site != null, "Sited component is not really sited: " + sitedComponent.ToString());
if (sitedComponent != null) Debug.Assert(TypeDescriptor.GetComponentName(sitedComponent) != null, "Sited component has no name: " + sitedComponent.ToString());
#endif // DEBUG
}
///
/// Resets the name of this reference holder. It will be re-aquired on demand
///
internal void ResetName() {
_fullName = null;
}
///
/// The name of the reference we are holding.
///
internal string Name {
get {
if (_fullName == null) {
if (_sitedComponent != null) {
string siteName = TypeDescriptor.GetComponentName(_sitedComponent);
if (siteName != null) {
_fullName = string.Format(CultureInfo.CurrentCulture, "{0}{1}", siteName, _trailingName);
}
}
if (_fullName == null) {
_fullName = string.Empty;
#if DEBUG
if (_sitedComponent != null) Debug.Assert(_sitedComponent.Site != null, "Sited component is not really sited: " + _sitedComponent.ToString());
if (_sitedComponent != null) Debug.Assert(TypeDescriptor.GetComponentName(_sitedComponent) != null, "Sited component has no name: " + _sitedComponent.ToString());
#endif // DEBUG
}
}
return _fullName;
}
}
///
/// The reference we are holding.
///
internal object Reference {
get {
return _reference;
}
}
///
/// The sited component associated with this reference.
///
internal IComponent SitedComponent {
get {
return _sitedComponent;
}
}
}
}
}
// 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
- EmissiveMaterial.cs
- DynamicValueConverter.cs
- ObjectItemCachedAssemblyLoader.cs
- Graphics.cs
- PropertyToken.cs
- OperationInfoBase.cs
- TextChange.cs
- GenerateHelper.cs
- WindowsPrincipal.cs
- TreeNodeEventArgs.cs
- ComplusTypeValidator.cs
- PersonalizationState.cs
- DataGridViewBand.cs
- WebPartTransformerAttribute.cs
- DocumentPaginator.cs
- LoginUtil.cs
- AutoSizeToolBoxItem.cs
- WarningException.cs
- CaseCqlBlock.cs
- AbstractExpressions.cs
- TypedReference.cs
- ProfileGroupSettings.cs
- BoolLiteral.cs
- ZipIOFileItemStream.cs
- XPathArrayIterator.cs
- ListControl.cs
- MergablePropertyAttribute.cs
- Exceptions.cs
- WebBrowserContainer.cs
- WebPartVerbCollection.cs
- PeerNeighborManager.cs
- RuntimeConfigLKG.cs
- EncoderBestFitFallback.cs
- ColorDialog.cs
- MailHeaderInfo.cs
- ping.cs
- WebCategoryAttribute.cs
- CustomAttributeSerializer.cs
- ConfigurationFileMap.cs
- CryptoConfig.cs
- RandomNumberGenerator.cs
- AutoGeneratedFieldProperties.cs
- PersianCalendar.cs
- ToolTipService.cs
- PropertyEmitterBase.cs
- DataServiceException.cs
- MetadataArtifactLoaderFile.cs
- DataServiceEntityAttribute.cs
- Expander.cs
- CodeDelegateCreateExpression.cs
- Timer.cs
- MaskDescriptors.cs
- BufferedMessageData.cs
- AssemblyInfo.cs
- Transform3DGroup.cs
- MemberPath.cs
- StringArrayEditor.cs
- Stacktrace.cs
- SqlDataSourceCache.cs
- EndpointIdentityConverter.cs
- LinkConverter.cs
- DurableOperationAttribute.cs
- StreamGeometryContext.cs
- ColorConvertedBitmap.cs
- ListViewItemEventArgs.cs
- PropertyToken.cs
- SerTrace.cs
- WebScriptMetadataFormatter.cs
- Ray3DHitTestResult.cs
- InputScopeAttribute.cs
- Column.cs
- DynamicQueryStringParameter.cs
- UIPermission.cs
- PagesSection.cs
- HealthMonitoringSection.cs
- SQLByte.cs
- BookmarkScopeManager.cs
- IisTraceListener.cs
- NotificationContext.cs
- DateBoldEvent.cs
- shaperfactory.cs
- ColorConvertedBitmapExtension.cs
- TableLayoutStyleCollection.cs
- TypeForwardedToAttribute.cs
- PageContent.cs
- Utility.cs
- WebBrowserContainer.cs
- DesignerActionVerbList.cs
- PrintDialogException.cs
- UITypeEditor.cs
- KerberosTicketHashIdentifierClause.cs
- GradientBrush.cs
- TcpTransportBindingElement.cs
- HostedNamedPipeTransportManager.cs
- LambdaCompiler.Generated.cs
- ReversePositionQuery.cs
- WebServiceEnumData.cs
- AttributeCollection.cs
- CollectionDataContractAttribute.cs
- ReadOnlyDataSourceView.cs