Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Annotations / Component / AdornerPresentationContext.cs / 2 / AdornerPresentationContext.cs
//---------------------------------------------------------------------------- //// Copyright(C) Microsoft Corporation. All rights reserved. // // // Description: // AdornerPresentationContext knows that annotation comonents are wrapped // in an AnnotationAdorner and hosted in the AdornerLayer. Note, implementation-wise // a new PresentationContext is created for every annotation component. Executing // operations on a presentation context for a different annotation component // (located in the same adorner layer) works, but is slower than using the // presentation context stored in the annotation component. // // History: // 04/01/2004: [....]: Created AdornerPresentationContext.cs // 10/20/2004: [....]: Moved class to MS.Internal. // // Copyright(C) 2002 by Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Diagnostics; using System.Windows; using System.Windows.Annotations; using System.Windows.Documents; using System.Windows.Media; using System.Collections; namespace MS.Internal.Annotations.Component { ////// AdornerPresentationContext knows that annotation comonents are wrapped in an AnnotationAdorner and hosted in the AdornerLayer. /// Note, implementation-wise a new PresentationContext is created for every annotation component. Executing operations on a presentation context /// for a different annotation component (located in the same adorner layer) works, but is slower than using the presentation context stored in the /// annotation component. /// internal class AdornerPresentationContext : PresentationContext { #region Constructors ////// Create an initialized instance of an AdornerPresentationContext. Set the presentation context of the /// component wrapped in the adorner /// /// AdornerLayer this presentation context is on, must not be null /// AnnotationAdorner that wraps the annotation component. Will be null in case of creating enclosing context private AdornerPresentationContext(AdornerLayer adornerLayer, AnnotationAdorner adorner) { if (adornerLayer == null) throw new ArgumentNullException("adornerLayer"); _adornerLayer = adornerLayer; if (adorner != null) { if (adorner.AnnotationComponent == null) throw new ArgumentNullException("annotation component"); if (adorner.AnnotationComponent.PresentationContext != null) throw new InvalidOperationException(SR.Get(SRID.ComponentAlreadyInPresentationContext, adorner.AnnotationComponent)); _annotationAdorner = adorner; } } #endregion Constructors #region Static Methods ////// Host a component in an adorner layer. /// Wrap the component in an annotation adorner, add that to the adorner layer, create and set presentation context and invalidate to pick up styles. /// Note, this is called from two places: (1) component manager to host choosen annotation component, and (2) presentation context when component /// adds additional IAnnotationComponent. /// /// Adorner layer the component is hosted in /// Component that is being hosted /// element being annotated /// if true - put the component on top and calculate its z-order internal static void HostComponent(AdornerLayer adornerLayer, IAnnotationComponent component, UIElement annotatedElement, bool reorder) { AnnotationAdorner newAdorner = new AnnotationAdorner(component, annotatedElement); // Create the context for the layer and adorner, make sure the adorner's component has its context. newAdorner.AnnotationComponent.PresentationContext = new AdornerPresentationContext(adornerLayer, newAdorner); int level = GetComponentLevel(component); if (reorder) { component.ZOrder = GetNextZOrder(adornerLayer, level); } adornerLayer.Add(newAdorner, ComponentToAdorner(component.ZOrder, level)); } ////// Sets the Z-order level of an annotation Component type /// /// the component type /// level - 0 means on top of all other types, bigger number means /// lower level ///ZLevel defines the Z-order disposition of this component type according to other /// component types in the same adorner layer. Components with lower ZLevel will be instantiated /// on top of the components with Higher ZLevel. /// The Z-order of all the components with the same ZLevel is defined by the value of /// IAnnotationComponent.ZOrder property with zero meaning the component is on top of all other /// inside the same level. ZOrder property can be changed by invoking /// BringToTop method. This will move the component to the top of its priority group. If there are other /// components with higher priority they will still be on top of that component. If more than /// one component type have the same ZLevel that means they all can stay on top of each other. /// Setting IAnnotationComponent.ZOrder must be invoked only by the PrezentationContext /// when the Z-order changes. It can not be set by application in v1. internal static void SetTypeZLevel(Type type, int level) { Invariant.Assert(level >= 0, "level is < 0"); Invariant.Assert(type != null, "type is null"); if (_ZLevel.ContainsKey(type)) { _ZLevel[type] = level; } else { _ZLevel.Add(type, level); } } ////// the allowed Z-order values range for this level. /// Used to define minimal Z-order value for types that are supposed to live above TextSelection /// which has a fixed Z-order value /// /// the Z-order level /// min Z-order value for this level /// max Z-order value for this level internal static void SetZLevelRange(int level, int min, int max) { if (_ZRanges[level] == null) { _ZRanges.Add(level, new ZRange(min, max)); } } #endregion Static Methods #region Public Properties ////// Returns the adorner layer which acts as a host for annotation components managed by the annotation component manager /// ///UIElement for the adorner layer public override UIElement Host { get { return _adornerLayer; } } ////// Get the enclosing presentation context. /// ///Enclosing PresentationContext or null if there is none public override PresentationContext EnclosingContext { get { Visual parent = VisualTreeHelper.GetParent(_adornerLayer) as Visual; if (parent == null) return null; AdornerLayer parentLayer = AdornerLayer.GetAdornerLayer((UIElement)parent); if (parentLayer == null) return null; PresentationContext p = new AdornerPresentationContext(parentLayer, null); return p; } } #endregion Public Properties #region Public Methods ////// Add the component to the adornerlayer of this presentation context. /// Create a new presentation context which includes the wrapped annotation adorner and the adornerlayer. /// Assign new presentation context into the component. /// /// Component to add to host public override void AddToHost(IAnnotationComponent component) { if (component == null) throw new ArgumentNullException("component"); AdornerPresentationContext.HostComponent(_adornerLayer, component, component.AnnotatedElement, false); } ////// Remove annotation component from host; in our case: respective annotation adorner from adornerLayer. /// If this presentation context does not contain the component search the adorner layer. /// Null out the presentation context of the component and set the local annotationAdorner to null if necessary, /// ask the annotation adorner to remove all visual children. /// /// Component to remove from host /// if true - recalculate z-order public override void RemoveFromHost(IAnnotationComponent component, bool reorder) { if (component == null) throw new ArgumentNullException("component"); if (IsInternalComponent(component)) { _annotationAdorner.AnnotationComponent.PresentationContext = null; _adornerLayer.Remove(_annotationAdorner); _annotationAdorner.RemoveChildren(); _annotationAdorner = null; } else {// need to find annotation adorner in layer, remove it and do house-keeping AnnotationAdorner foundAdorner = this.FindAnnotationAdorner(component); if (foundAdorner == null) throw new InvalidOperationException(SR.Get(SRID.ComponentNotInPresentationContext, component)); _adornerLayer.Remove(foundAdorner); foundAdorner.RemoveChildren(); // now get rid of reference from presentation context of annotation component to annotation adorner AdornerPresentationContext p = component.PresentationContext as AdornerPresentationContext; if (p != null) p.ResetInternalAnnotationAdorner(); // finally get rid of reference from annotation component to presentation context component.PresentationContext = null; } } ////// Invalidate the transform for this adorner. called when adorner inside changed aspects of the transform. /// This might go away if InvalidateMeasure works /// (unclear if Peter means this should work on the adorner or even one down on the annotation component itself) /// /// Component to invalidate transform for public override void InvalidateTransform(IAnnotationComponent component) { AnnotationAdorner adorner = GetAnnotationAdorner(component); adorner.InvalidateTransform(); } ////// Sets a component on top of its ZLevel /// /// Component to change z-order of public override void BringToFront(IAnnotationComponent component) { AnnotationAdorner adorner = GetAnnotationAdorner(component); int level = GetComponentLevel(component); int nextLevel = GetNextZOrder(_adornerLayer, level); // Only change the ZOrder if its not already on the top if (nextLevel != component.ZOrder + 1) { component.ZOrder = nextLevel; _adornerLayer.SetAdornerZOrder(adorner, ComponentToAdorner(component.ZOrder, level)); } } ////// Sets a component on bttom of its ZLevel /// /// Component to change z-order of public override void SendToBack(IAnnotationComponent component) { AnnotationAdorner adorner = GetAnnotationAdorner(component); int level = GetComponentLevel(component); // Only change the ZOrder if its not already on the bottom if (0 != component.ZOrder) { component.ZOrder = 0; UpdateComponentZOrder(component); } } ////// Determines if the passed in object is equal to this object. /// Two AdornerPresentationContexts will be equal if they both have the same adorner layer. /// /// The object to compare with. ///True if the objects are equal. False otherwise. public override bool Equals(object o) { AdornerPresentationContext p = o as AdornerPresentationContext; if (p != null) { return (p._adornerLayer == this._adornerLayer); } return false; } ////// overload operator for ==, to be same as Equal implementation. /// /// AdornerPresentationContext to compare /// AdornerPresentationContext to compare ///public static bool operator ==(AdornerPresentationContext left, AdornerPresentationContext right) { if ((object)left == null) return (object)right == null; return left.Equals(right); } /// /// overload operator for !=, to go along with definition for == /// /// AdornerPresentationContext to compare /// AdornerPresentationContext to compare ///public static bool operator !=(AdornerPresentationContext c1, AdornerPresentationContext c2) { return !(c1 == c2); } /// /// Delegate hash to adorner layer /// public override int GetHashCode() { return (int)this._adornerLayer.GetHashCode(); } ////// Updates the ZOrder of the input component and on all components with the same ZLevel /// that have same or bigger Z-order as the input component on a given adorner layer /// /// the component public void UpdateComponentZOrder(IAnnotationComponent component) { Invariant.Assert(component != null, "null component"); //check Z-order range for this level int level = GetComponentLevel(component); //get the component's adorner AnnotationAdorner adorner = FindAnnotationAdorner(component); if (adorner == null) return; //set the adorner z-order _adornerLayer.SetAdornerZOrder(adorner, ComponentToAdorner(component.ZOrder, level)); Listadorners = GetTopAnnotationAdorners(level, component); if (adorners == null) return; int lastZOrder = component.ZOrder + 1; foreach (AnnotationAdorner topAdorner in adorners) { topAdorner.AnnotationComponent.ZOrder = lastZOrder; _adornerLayer.SetAdornerZOrder(topAdorner, ComponentToAdorner(lastZOrder, level)); lastZOrder++; } } #endregion Public Methods #region Private Methods /// /// Reset the annotation adorner to null. This is needed for reset of found adorner in method RemoveFromHost /// private void ResetInternalAnnotationAdorner() { _annotationAdorner = null; } ////// Return true if the given annotation component is the one this presentation context is on. /// /// The component that might be referred to by this presentation context ///True if the component is internal private bool IsInternalComponent(IAnnotationComponent component) { return _annotationAdorner != null && component == _annotationAdorner.AnnotationComponent; } ////// Return the annotation adorner for the given annotation component. /// will not look at local annotation adorner, will always iterate through annotation adorners of adorner layer. /// Return null if none can be found. /// /// The component that is wrapped by an annotation adorner ///The annotation adorner that wraps the component in the adorner layer associated with this presentation context private AnnotationAdorner FindAnnotationAdorner(IAnnotationComponent component) { if (_adornerLayer == null) return null; foreach (Adorner adorner in _adornerLayer.GetAdorners(component.AnnotatedElement)) { AnnotationAdorner annotationAdorner = adorner as AnnotationAdorner; if (annotationAdorner != null && annotationAdorner.AnnotationComponent == component) return annotationAdorner; } return null; } ////// Finds all AnnotationAddorners from particular Z-level that have the same or bigger z-order as the component /// /// the ZLevel of interest /// the component ///the AnnotationAdorner children private ListGetTopAnnotationAdorners(int level, IAnnotationComponent component) { List res = new List (); int count = VisualTreeHelper.GetChildrenCount(_adornerLayer); if (count == 0) return res; for (int i = 0; i < count; i++) { DependencyObject child = VisualTreeHelper.GetChild(_adornerLayer, i); AnnotationAdorner adorner = child as AnnotationAdorner; if (adorner != null) { IAnnotationComponent childComponent = adorner.AnnotationComponent; if ((childComponent != component) && (GetComponentLevel(childComponent) == level) && (childComponent.ZOrder >= component.ZOrder)) { AddAdorner(res, adorner); } } } return res; } /// /// Inserts an adorner after the last adorner with ZOrder less or equal of the input one /// /// adorners list /// the new adorner ///In most cases the AnnotationAdorners are already orderd so we expect that the new one /// will be added at the end of the list. That is why we start scaning from the end. private void AddAdorner(Listadorners, AnnotationAdorner adorner) { Debug.Assert((adorners != null) && (adorner != null), "null adorners list or adorner"); int index = 0; if (adorners.Count > 0) { for (index = adorners.Count; index > 0; index--) { if (adorners[index-1].AnnotationComponent.ZOrder <= adorner.AnnotationComponent.ZOrder) break; } } adorners.Insert(index, adorner); } /// /// Gets the next free Z-order value for the components in this level /// /// adorner layer /// Z-level ///next free Z-order value private static int GetNextZOrder(AdornerLayer adornerLayer, int level) { Invariant.Assert(adornerLayer != null, "null adornerLayer"); int res = 0; int count = VisualTreeHelper.GetChildrenCount(adornerLayer); if (count == 0) return res; for ( int i = 0; i < count; i++) { DependencyObject child = VisualTreeHelper.GetChild(adornerLayer, i); AnnotationAdorner adorner = child as AnnotationAdorner; if (adorner != null) { if ((GetComponentLevel(adorner.AnnotationComponent) == level) && (adorner.AnnotationComponent.ZOrder >= res)) { res = adorner.AnnotationComponent.ZOrder + 1; } } } return res; } ////// Finds the correct AdornerLayer where a component lives /// /// the component ///private AnnotationAdorner GetAnnotationAdorner(IAnnotationComponent component) { if (component == null) throw new ArgumentNullException("component"); //find the adornerLayer AnnotationAdorner adorner = _annotationAdorner; if (!this.IsInternalComponent(component)) { adorner = this.FindAnnotationAdorner(component); if (adorner == null) throw new InvalidOperationException(SR.Get(SRID.ComponentNotInPresentationContext, component)); } return adorner; } /// /// Returns the component ZLevel /// /// component ///ZLevel private static int GetComponentLevel(IAnnotationComponent component) { int level = 0; Type type = component.GetType(); if (_ZLevel.ContainsKey(type)) level = (int)_ZLevel[type]; return level; } ////// Converts the component z-order to the Adorner z-order. The adorner z-order /// is shifted by the minimal value for this level. Also there is a restriction /// about the maximal possible value for this level too /// /// component z-order /// component z-level ///private static int ComponentToAdorner(int zOrder, int level) { int res = zOrder; ZRange range = (ZRange)_ZRanges[level]; if (range != null) { //adjust the Z-order (shift it with the minimal value for this range) //that way the component does need to know the range for its type that is // set by the application. It always sets the z-order as it starts from 0 res += range.Min; if (res < range.Min) res = range.Min; if (res > range.Max) res = range.Max; } return res; } #endregion Private Methods #region Private Fields /// /// The annotation adorner which wraps the annotation component this presentation context is optimized for. /// Can be null. /// private AnnotationAdorner _annotationAdorner = null; ////// The adornerLayer which contains the annotation component. Basically what the presentation hides. /// private AdornerLayer _adornerLayer; ////// The hashtable holds the priority level for each Component type as defined by the application /// private static Hashtable _ZLevel = new Hashtable(); ////// The ZRanges for the ZLevels. /// private static Hashtable _ZRanges = new Hashtable(); #endregion Private Fields #region Private classes ////// This is to control the relationships with TextSelection which lives in the same /// AdornerLayer. Will be removed when more flexible Z-ordering mechanism is available /// private class ZRange { public ZRange(int min, int max) { //exchange values if needed if (min > max) { int temp = min; min = max; max = temp; } _min = min; _max = max; } public int Min { get { return _min; } } public int Max { get { return _max; } } private int _min, _max; } #endregion Internal classes } } // 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
- AttributeSetAction.cs
- EventLogPermission.cs
- TabletDevice.cs
- InvalidOperationException.cs
- PeerMessageDispatcher.cs
- WindowsListViewGroupHelper.cs
- ScrollChrome.cs
- PathSegment.cs
- DesignerActionGlyph.cs
- CatalogPartCollection.cs
- TabletDevice.cs
- DeclarativeCatalogPart.cs
- Converter.cs
- ValueUnavailableException.cs
- ErrorInfoXmlDocument.cs
- SerTrace.cs
- DefaultTraceListener.cs
- FlowLayoutPanel.cs
- UxThemeWrapper.cs
- TrustManager.cs
- EqualityComparer.cs
- ModuleElement.cs
- DefaultPropertiesToSend.cs
- Wildcard.cs
- ListSortDescriptionCollection.cs
- MultiTouchSystemGestureLogic.cs
- HttpPostServerProtocol.cs
- SQLInt64Storage.cs
- ApplicationActivator.cs
- _DisconnectOverlappedAsyncResult.cs
- EqualityComparer.cs
- FormViewModeEventArgs.cs
- DocumentXPathNavigator.cs
- Clause.cs
- MDIControlStrip.cs
- StringBuilder.cs
- UrlAuthFailedErrorFormatter.cs
- KeyEvent.cs
- RtfFormatStack.cs
- Pair.cs
- RelationshipFixer.cs
- ClientSettingsSection.cs
- SystemResources.cs
- EtwTrackingBehavior.cs
- ToolStripGripRenderEventArgs.cs
- SimpleTypeResolver.cs
- Clipboard.cs
- ProfilePropertyNameValidator.cs
- ControlPersister.cs
- FileDetails.cs
- AsmxEndpointPickerExtension.cs
- CLSCompliantAttribute.cs
- ExplicitDiscriminatorMap.cs
- SafeArrayTypeMismatchException.cs
- SpeakProgressEventArgs.cs
- WeakReferenceList.cs
- MbpInfo.cs
- BehaviorDragDropEventArgs.cs
- XmlCodeExporter.cs
- IntPtr.cs
- XmlSchemaExporter.cs
- Rotation3DAnimationUsingKeyFrames.cs
- SspiWrapper.cs
- SafeEventLogWriteHandle.cs
- ProjectionPruner.cs
- XmlSchemaSimpleTypeUnion.cs
- ArraySegment.cs
- LazyInitializer.cs
- SynchronizationLockException.cs
- TextTreeDeleteContentUndoUnit.cs
- AnnotationComponentManager.cs
- Command.cs
- ComponentEditorPage.cs
- ExeContext.cs
- SynchronousSendBindingElement.cs
- DataGridTextBoxColumn.cs
- SortFieldComparer.cs
- OdbcEnvironmentHandle.cs
- MsmqAuthenticationMode.cs
- ArithmeticException.cs
- WindowsListViewGroupHelper.cs
- XmlWrappingReader.cs
- ButtonBaseAutomationPeer.cs
- WebPartTransformerAttribute.cs
- AssemblyInfo.cs
- Activity.cs
- DeploymentSection.cs
- Storyboard.cs
- TabPage.cs
- XmlCountingReader.cs
- StoreItemCollection.cs
- EmissiveMaterial.cs
- HtmlTable.cs
- TextComposition.cs
- Classification.cs
- SqlPersonalizationProvider.cs
- FillRuleValidation.cs
- CacheAxisQuery.cs
- CodeThrowExceptionStatement.cs
- ReadOnlyHierarchicalDataSourceView.cs