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
- ChildChangedEventArgs.cs
- ClassDataContract.cs
- CodeMemberField.cs
- KeyInterop.cs
- InstancePersistenceException.cs
- OutputCacheProfileCollection.cs
- CharacterMetricsDictionary.cs
- Random.cs
- ClientConfigurationHost.cs
- ClientTargetCollection.cs
- FileUtil.cs
- MaskInputRejectedEventArgs.cs
- ClassGenerator.cs
- GenericWebPart.cs
- ReferencedType.cs
- PanelStyle.cs
- Error.cs
- ScrollProviderWrapper.cs
- DSASignatureFormatter.cs
- CodeObject.cs
- IdentitySection.cs
- ManagementObjectSearcher.cs
- NotFiniteNumberException.cs
- SharedConnectionInfo.cs
- WCFServiceClientProxyGenerator.cs
- CodeCatchClause.cs
- RowToParametersTransformer.cs
- ProcessThreadDesigner.cs
- SoapHeaders.cs
- TcpHostedTransportConfiguration.cs
- SimpleModelProvider.cs
- Memoizer.cs
- ParserHooks.cs
- AssertUtility.cs
- PropertyGridCommands.cs
- _ShellExpression.cs
- StatusBar.cs
- ObjectQuery.cs
- PingReply.cs
- DataGridViewRowPrePaintEventArgs.cs
- PathStreamGeometryContext.cs
- GroupLabel.cs
- InvokePattern.cs
- ErrorFormatter.cs
- GridViewRowPresenterBase.cs
- UriParserTemplates.cs
- ProcessThreadCollection.cs
- AspNetCacheProfileAttribute.cs
- SvcFileManager.cs
- ConfigXmlAttribute.cs
- VectorAnimationBase.cs
- HttpCapabilitiesEvaluator.cs
- XmlNamespaceManager.cs
- _ScatterGatherBuffers.cs
- ProxyAttribute.cs
- ProgressBarRenderer.cs
- NullableBoolConverter.cs
- NamedServiceModelExtensionCollectionElement.cs
- Vars.cs
- ContainerUtilities.cs
- Block.cs
- ValueTypeFixupInfo.cs
- MetadataSerializer.cs
- GeneralTransformCollection.cs
- Ray3DHitTestResult.cs
- AutomationPropertyInfo.cs
- ViewValidator.cs
- ImplicitInputBrush.cs
- MetadataSet.cs
- GridLengthConverter.cs
- Point4D.cs
- CollectionViewGroupRoot.cs
- XmlWhitespace.cs
- Rectangle.cs
- SQLBinary.cs
- DataIdProcessor.cs
- httpstaticobjectscollection.cs
- SqlTypeConverter.cs
- infer.cs
- DbExpressionBuilder.cs
- ResetableIterator.cs
- CodeVariableReferenceExpression.cs
- AnnotationDocumentPaginator.cs
- HtmlTitle.cs
- PropertyGridEditorPart.cs
- ShaderEffect.cs
- WebEventCodes.cs
- EntityProviderServices.cs
- ProjectedWrapper.cs
- JsonObjectDataContract.cs
- PrintPageEvent.cs
- InputProcessorProfiles.cs
- RegionIterator.cs
- PackageRelationship.cs
- storepermission.cs
- SoapExtensionTypeElement.cs
- DataRowView.cs
- OleDbRowUpdatingEvent.cs
- Model3DCollection.cs
- Wizard.cs