Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / Drawing / System / Drawing / Design / DesignerToolboxInfo.cs / 1 / DesignerToolboxInfo.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Drawing.Design { using System; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; ////// This object lives as a service on a designer host /// and provides per-designer toolbox information, such /// as the filter and current toolbox user. /// internal sealed class DesignerToolboxInfo : IDisposable { private ToolboxService _toolboxService; private IDesignerHost _host; private ISelectionService _selectionService; private ArrayList _filter; private IDesigner _filterDesigner; private IToolboxUser _toolboxUser; private Hashtable _attributeHash; ////// Creates a new toolbox designer state object. /// internal DesignerToolboxInfo(ToolboxService toolboxService, IDesignerHost host) { _toolboxService = toolboxService; _host = host; _selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService; if (_selectionService != null) { _selectionService.SelectionChanged += new EventHandler(OnSelectionChanged); } if(_host.RootComponent != null) { _host.RootComponent.Disposed += new EventHandler(OnDesignerDisposed); } TypeDescriptor.Refreshed += new RefreshEventHandler(OnTypeDescriptorRefresh); } ////// Returns the designer host this toolbox state object /// is associated with. /// internal IDesignerHost DesignerHost { get { return _host; } } ////// Returns the current toolbox item filter. /// internal ICollection Filter { get { if (_filter == null) { Update(); } return _filter; } } ////// Returns the current toolbox user. /// internal IToolboxUser ToolboxUser { get { if (_toolboxUser == null) { Update(); } return _toolboxUser; } } private void OnTypeDescriptorRefresh(RefreshEventArgs r) { if (r.ComponentChanged == _filterDesigner) { _filter = null; _filterDesigner = null; } } ////// The GetDesignerAttributes method is used to retrieve a collection of attributes for /// the specified designer. If the designer implements ITreeDesigner, this method will /// also collect attributes for all parent designers. Attributes are merged such that /// child attributes replace matching parent attributes. /// public AttributeCollection GetDesignerAttributes(IDesigner designer) { if (designer == null) { throw new ArgumentNullException("designer"); } AttributeCollection attributes; // We don't store the merged attribute set. If we // did, we would have to also store what designer // the merge was for, and then we would have to worry // about designer GC and cleaning out our table. That // would be a pain. But we do re-use the same // hashtable over and over so we don't have to "new" // one each time. This keeps the buckets preallocated. // if (_attributeHash == null) { _attributeHash = new Hashtable(); } else { _attributeHash.Clear(); } // If the designer is a designer tree, then we rely // on the designer's "treeness" to get to the root. // If it's not, then we include the root designer // directly. if (!(designer is ITreeDesigner)) { IComponent root = _host.RootComponent; if (root != null) { RecurseDesignerTree(_host.GetDesigner(root), _attributeHash); } } RecurseDesignerTree(designer, _attributeHash); Attribute[] attributeArray = new Attribute[_attributeHash.Values.Count]; _attributeHash.Values.CopyTo(attributeArray, 0); attributes = new AttributeCollection(attributeArray); return attributes; } ////// Recurive algorithm to walk the designer tree for attributes. /// private void RecurseDesignerTree(IDesigner designer, Hashtable table) { ITreeDesigner tree = designer as ITreeDesigner; if (tree != null) { IDesigner parent = tree.Parent; if (parent != null) { RecurseDesignerTree(parent, table); } } foreach(Attribute a in TypeDescriptor.GetAttributes(designer)) { table[a.TypeId] = a; } } private void OnDesignerDisposed(object sender, EventArgs e) { _host.RemoveService(typeof(DesignerToolboxInfo)); } ////// Called when the designer selection changes. This recomputes the filter and /// toolbox user data based on the primary selection. If this is the /// currently active designer it will notify the toolbox service that /// the filter has changed. The toolbox service will raise its FilterChanged /// event. /// private void OnSelectionChanged(object sender, EventArgs e) { if (Update()) { _toolboxService.OnDesignerInfoChanged(this); } } ////// Called to recalculate our designer filter and toolbox /// user. This will return true if the state has changed /// in such a way as to require a requery of the toolbox item /// enabling. For exapmle, if the toolbox user changes, but /// the filter didn't change (and the filter didn't specify /// "Custom"), then this will return false. If the /// filter changes, or if a custom filter is specified and /// the toolbox user changes, this will return true. /// private bool Update() { Debug.Assert(_selectionService != null, "Should not have a null service inside this event handler."); bool update = false; IDesigner targetDesigner = null; IComponent target = _selectionService.PrimarySelection as IComponent; if (target != null) { targetDesigner = _host.GetDesigner(target); } if (targetDesigner == null) { target = _host.RootComponent; if (target != null) { targetDesigner = _host.GetDesigner(target); } } if (targetDesigner != _filterDesigner) { // We have a new designer. This could mean that // the filter we have aquired is no longer valid. // Compute a new filter. // ArrayList newFilter; if (targetDesigner != null) { AttributeCollection newAttributes = GetDesignerAttributes(targetDesigner); newFilter = new ArrayList(newAttributes.Count); foreach(Attribute a in newAttributes) { if (a is ToolboxItemFilterAttribute) { newFilter.Add(a); } } } else { newFilter = new ArrayList(); } if (_filter == null) { update = true; } else if (_filter.Count != newFilter.Count) { update = true; } else { IEnumerator lastEnum = _filter.GetEnumerator(); IEnumerator newEnum = newFilter.GetEnumerator(); while(newEnum.MoveNext()) { lastEnum.MoveNext(); if (!newEnum.Current.Equals(lastEnum.Current)) { update = true; break; } else { // For custom filters, a change in the current designer could // cause the toolbox item enabling to change, so we must always // update ourselves for custom filters. // ToolboxItemFilterAttribute attr = (ToolboxItemFilterAttribute)newEnum.Current; if (attr.FilterType == ToolboxItemFilterType.Custom) { update = true; break; } } } } _filter = newFilter; _filterDesigner = targetDesigner; _toolboxUser = _filterDesigner as IToolboxUser; if (_toolboxUser == null) { ITreeDesigner tree = _filterDesigner as ITreeDesigner; while(_toolboxUser == null && tree != null) { IDesigner designer = tree.Parent; _toolboxUser = designer as IToolboxUser; tree = designer as ITreeDesigner; } } if (_toolboxUser == null && _host.RootComponent != null) { _toolboxUser = _host.GetDesigner(_host.RootComponent) as IToolboxUser; } } if (_filter == null) { _filter = new ArrayList(); } return update; } ////// This object is added as a service to the designer, and automatically /// disposed upon designer shutdown. /// void IDisposable.Dispose() { if (_selectionService != null) { _selectionService.SelectionChanged -= new EventHandler(OnSelectionChanged); } if(_host.RootComponent != null) { _host.RootComponent.Disposed -= new EventHandler(OnDesignerDisposed); } TypeDescriptor.Refreshed -= new RefreshEventHandler(OnTypeDescriptorRefresh); } } } // 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
- TableRow.cs
- GcHandle.cs
- HttpWriter.cs
- CalloutQueueItem.cs
- ListDictionaryInternal.cs
- MessageProtectionOrder.cs
- WebConfigurationManager.cs
- FieldBuilder.cs
- ConfigXmlSignificantWhitespace.cs
- IncrementalReadDecoders.cs
- FormattedText.cs
- TextDecorationCollection.cs
- DBSchemaRow.cs
- ErrorHandler.cs
- ButtonBaseAutomationPeer.cs
- SatelliteContractVersionAttribute.cs
- XmlSchemas.cs
- CachedFontFamily.cs
- CssTextWriter.cs
- GlyphRunDrawing.cs
- LineGeometry.cs
- SplineQuaternionKeyFrame.cs
- DllNotFoundException.cs
- DataRecordInternal.cs
- AccessedThroughPropertyAttribute.cs
- Scene3D.cs
- TrackingServices.cs
- CallContext.cs
- BitmapFrameEncode.cs
- UniqueIdentifierService.cs
- WebPartConnectVerb.cs
- RecordConverter.cs
- ScriptHandlerFactory.cs
- SoapAttributes.cs
- SqlCacheDependencyDatabase.cs
- FunctionUpdateCommand.cs
- PointUtil.cs
- ServiceModelInstallComponent.cs
- TogglePattern.cs
- QueryTask.cs
- ResourceProviderFactory.cs
- WebPartEditorOkVerb.cs
- PropertySegmentSerializationProvider.cs
- ResourcePool.cs
- SingleBodyParameterMessageFormatter.cs
- DataGridLinkButton.cs
- TypedDataSetSchemaImporterExtension.cs
- BindingWorker.cs
- DataGridItemCollection.cs
- DataObjectAttribute.cs
- _LoggingObject.cs
- SID.cs
- CachedCompositeFamily.cs
- PathFigure.cs
- DataSetUtil.cs
- XAMLParseException.cs
- SymmetricKey.cs
- FastPropertyAccessor.cs
- TypeLibConverter.cs
- HttpErrorTraceRecord.cs
- SQLInt32Storage.cs
- ActivityStatusChangeEventArgs.cs
- XmlDeclaration.cs
- X509PeerCertificateElement.cs
- XmlSchemaNotation.cs
- PropertyCondition.cs
- EventDescriptorCollection.cs
- ChangeTracker.cs
- ReaderWriterLockWrapper.cs
- XhtmlTextWriter.cs
- WMIInterop.cs
- EpmContentDeSerializerBase.cs
- GlyphsSerializer.cs
- Rotation3D.cs
- XDeferredAxisSource.cs
- ExtensionSimplifierMarkupObject.cs
- ComboBoxRenderer.cs
- PolicyValidationException.cs
- UnitySerializationHolder.cs
- Pkcs7Recipient.cs
- XpsTokenContext.cs
- ITreeGenerator.cs
- _FtpDataStream.cs
- HtmlFormWrapper.cs
- RadioButtonAutomationPeer.cs
- PhonemeEventArgs.cs
- XmlDataSourceNodeDescriptor.cs
- CodeIdentifier.cs
- FrugalMap.cs
- StringOutput.cs
- SQLMoney.cs
- SqlClientWrapperSmiStreamChars.cs
- SystemInfo.cs
- FormatConvertedBitmap.cs
- ConnectionPoint.cs
- RSAPKCS1SignatureDeformatter.cs
- ControlEvent.cs
- ServiceModelConfigurationSectionCollection.cs
- MarkupCompilePass1.cs
- Asn1IntegerConverter.cs