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
- Vector3DValueSerializer.cs
- GeometryGroup.cs
- LinkLabel.cs
- ConnectionStringSettingsCollection.cs
- WebServiceErrorEvent.cs
- InputQueue.cs
- FixUp.cs
- LabelDesigner.cs
- HttpPostClientProtocol.cs
- CompilerCollection.cs
- WebPartUserCapability.cs
- ObjectNavigationPropertyMapping.cs
- CryptoApi.cs
- XPathParser.cs
- BasicViewGenerator.cs
- Triangle.cs
- ClassImporter.cs
- RemotingConfiguration.cs
- nulltextnavigator.cs
- TextDocumentView.cs
- RadioButton.cs
- StrongNameHelpers.cs
- FormViewDeletedEventArgs.cs
- LOSFormatter.cs
- LogExtentCollection.cs
- InputMethodStateTypeInfo.cs
- TreeNodeMouseHoverEvent.cs
- StringInfo.cs
- RecognizerInfo.cs
- SystemNetworkInterface.cs
- AutomationPropertyInfo.cs
- filewebrequest.cs
- PolygonHotSpot.cs
- ReadOnlyDataSourceView.cs
- Command.cs
- DES.cs
- SQLCharsStorage.cs
- PartitionResolver.cs
- AutomationPropertyInfo.cs
- Schema.cs
- XmlSchemaSubstitutionGroup.cs
- InputScopeConverter.cs
- AudioLevelUpdatedEventArgs.cs
- CacheRequest.cs
- SaveFileDialog.cs
- AtomServiceDocumentSerializer.cs
- DecimalStorage.cs
- AnimationTimeline.cs
- DynamicILGenerator.cs
- MenuItem.cs
- LinkedList.cs
- EnvironmentPermission.cs
- mediaeventargs.cs
- ImageIndexEditor.cs
- QueryAccessibilityHelpEvent.cs
- ConvertersCollection.cs
- WSFederationHttpBindingCollectionElement.cs
- MobileErrorInfo.cs
- HintTextMaxWidthConverter.cs
- CheckBoxPopupAdapter.cs
- XmlTextReader.cs
- dbenumerator.cs
- LocalizableResourceBuilder.cs
- ScalarConstant.cs
- RecommendedAsConfigurableAttribute.cs
- DBConnection.cs
- PenThreadPool.cs
- SrgsRulesCollection.cs
- FormClosingEvent.cs
- App.cs
- EntityEntry.cs
- AuthenticatedStream.cs
- EventHandlers.cs
- SqlConnectionHelper.cs
- SingleObjectCollection.cs
- Clause.cs
- _RequestCacheProtocol.cs
- CellPartitioner.cs
- NativeMethods.cs
- GlobalEventManager.cs
- X509Certificate.cs
- DbProviderFactory.cs
- SettingsPropertyCollection.cs
- StorageTypeMapping.cs
- ModelItemKeyValuePair.cs
- StringValidator.cs
- WindowsRichEditRange.cs
- PopupRootAutomationPeer.cs
- HitTestWithGeometryDrawingContextWalker.cs
- RowTypeElement.cs
- InternalPolicyElement.cs
- ValidatingReaderNodeData.cs
- Sequence.cs
- CustomErrorCollection.cs
- MemberProjectedSlot.cs
- HttpProfileGroupBase.cs
- DesignerVerb.cs
- TimeZoneNotFoundException.cs
- MultiplexingFormatMapping.cs
- Constraint.cs