Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / Annotations / Component / AnnotationComponentManager.cs / 1 / AnnotationComponentManager.cs
//----------------------------------------------------------------------------
//
// Copyright(C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// AnnotationComponentManager
//
// History:
// 04/01/2004 axelk: Created AnnotationComponentManager.cs
//
// 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;
namespace MS.Internal.Annotations.Component
{
///
/// Instances of this class manage listen for events from the annotation service and create/remove/modify annotation components in response.
/// Annotation components are created via indirection through an AnnotationComponentChooser which is set in a DP on the app tree.
/// Annotation components are hosted, wrapped inside AnnotationAdorners, in an AdornerLayer respective to the annotated element.
/// Every time an annotation service is instantiated an instance of this class is created.
///
internal class AnnotationComponentManager : DependencyObject
{
#region Constructors
///
/// Return an annotation component manager. If an annotation service is passed in, manager will
/// receive notification from the service. Otherwise it will expect to be called directly.
///
/// optional, annotation service the annotation component manager will register on
internal AnnotationComponentManager(AnnotationService service)
: base()
{
// Only register if a service was passed in. If no service was passed in, we will not receive events.
// This means a client will be calling us directly.
if (service != null)
{
service.AttachedAnnotationChanged += new AttachedAnnotationChangedEventHandler(AttachedAnnotationUpdateEventHandler);
}
}
#endregion Constructors
#region Internal Methods
///
/// The given attached annotation was added by the annotation service
/// Find annotation components for the given attached annotation, maintain
/// mapping from attached annotation to annotation components, and add to the
/// adorner layer if the annotation component is not already in a presentation context.
///
/// Attached annotation to add
/// If true - update components ZOrder after adding the component
internal void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
IAnnotationComponent component = FindComponent(attachedAnnotation);
if (component == null) return;
AddComponent(attachedAnnotation, component, reorder);
}
///
/// The given attached annotation was removed by the annotation service.
/// Find all annotation components and let them know.
/// If an annotation component does not have any other attached annotations, remove it.
/// Update the attachedAnnotations map.
///
/// Attached annotation to remove
/// If true - update components ZOrder after removing the component
internal void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
{
// note, this is not always a bug, since an annotation might have resolved, but no annotation component found
// the tree traversal bug we have currently results in this failing even if annotation components were found, because
// in certain cases annotationService.AttachedAnnotations returns wrong list.
return;
}
IList currentList = _attachedAnnotations[attachedAnnotation];
_attachedAnnotations.Remove(attachedAnnotation); // clean up the map
foreach (IAnnotationComponent component in currentList)
{
component.RemoveAttachedAnnotation(attachedAnnotation); // let the annotation component know
if (component.AttachedAnnotations.Count == 0)
{ // if it has no more attached annotations, remove it
if (component.PresentationContext != null)
component.PresentationContext.RemoveFromHost(component, reorder);
}
}
}
#endregion Internal Methods
#region Private Methods
///
/// Handle the notification coming from the service. Attached annotations can be added, removed, modified.
/// Delegate to appropriate method
///
/// The sender of the event, an annotation service
/// The event arguments containing information on added/deleted/modified attached annotation.
private void AttachedAnnotationUpdateEventHandler(object sender, AttachedAnnotationChangedEventArgs e)
{
switch (e.Action)
{
case AttachedAnnotationAction.Added:
this.AddAttachedAnnotation(e.AttachedAnnotation, true);
break;
case AttachedAnnotationAction.Deleted:
this.RemoveAttachedAnnotation(e.AttachedAnnotation, true);
break;
case AttachedAnnotationAction.Loaded:
this.AddAttachedAnnotation(e.AttachedAnnotation, false);
break;
case AttachedAnnotationAction.Unloaded:
this.RemoveAttachedAnnotation(e.AttachedAnnotation, false);
break;
case AttachedAnnotationAction.AnchorModified:
this.ModifyAttachedAnnotation(e.AttachedAnnotation, e.PreviousAttachedAnchor, e.PreviousAttachmentLevel);
break;
}
}
///
/// given an attachedAnnotation find the chooser attached at its parent
/// and ask it to choose a component suitable to handle the attachedAnnotation
///
/// the attachedAnnotation we are to find a component for
/// an IAnnotationComponent that can handle the attachedAnnotation (or null)
private IAnnotationComponent FindComponent(IAttachedAnnotation attachedAnnotation)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject
Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
AnnotationComponentChooser chooser = AnnotationService.GetChooser(annotatedElement);
// should we return a list instead?
IAnnotationComponent component = chooser.ChooseAnnotationComponent(attachedAnnotation);
return component;
}
///
/// Add an attached annotation to a component and add the component to the adorner layer
/// if the annotation component is not already in a presentation context.
///
/// the attachedAnnotation we are to add to the component
/// the component we are to add to the adorner layer
/// if true - the z-order must be reevaluated
private void AddComponent(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component, bool reorder)
{
UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject
Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
// if annotation component is already in presentation context, nothing else to do
if (component.PresentationContext != null) return;
// otherwise host in the appropriate adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(annotatedElement); // note, GetAdornerLayer requires UIElement
if (layer == null)
{
if (PresentationSource.FromVisual(annotatedElement) == null)
{
// The annotated element is no longer part of the application tree.
// This probably means we are out of [....] - trying to add an annotation
// for an element that has already gone away. Bug # 1580288 tracks
// the need to figure this out.
return;
}
throw new InvalidOperationException(SR.Get(SRID.NoPresentationContextForGivenElement, annotatedElement));
}
// add to the attachedAnnotations
this.AddToAttachedAnnotations(attachedAnnotation, component);
// let the annotation component know about the attached annotation
// call add before adding to adorner layer so the component can be initialized
component.AddAttachedAnnotation(attachedAnnotation); // this might cause recursion in modify if annotation component adds to annotation
AdornerPresentationContext.HostComponent(layer, component, annotatedElement, reorder);
}
///
/// Service indicates attached annotation has changed.
/// For now, take all annotation components maped from old attached annotation and map from new.
/// Then iterate through annotation components to let them know.
/// Note, this needs to change later. If modify is radical, existing component might not want it anymore,
/// and new one might need to be found...
///
/// The modified attached annotation
/// The previous attached anchor for the attached annotation
/// The previous attachment level for the attached annotation
private void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
{
Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null");
Debug.Assert(previousAttachedAnchor != null, "previousAttachedAnchor should not be null");
// if there was no component found for this attached annotation
// then we treat the modify case as an add
if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
{
// this is not necessarily a bug, it can be that the old attached annotation does not have an
// associated annotation component.
this.AddAttachedAnnotation(attachedAnnotation, true);
return;
}
// we have a previous component for this attached annotation
// we find the chooser for the new attached annotation
// and ask it to choose a component
// 1- if it returned null then we just remove the attached annotation
// 2- if it returned a different component, then we treat it as a remove/add
// 3- if it returned the same component then we call ModifyAttachedAnnotation on the component
IAnnotationComponent newComponent = FindComponent(attachedAnnotation);
if (newComponent == null)
{
RemoveAttachedAnnotation(attachedAnnotation, true);
}
else
{
IList currentList = _attachedAnnotations[attachedAnnotation]; //save the current list
// if we found the new component in any of the list of components we already have for this
// attached annotation
if (currentList.Contains(newComponent))
{
// ask the components to handle the anchor modification event
foreach (IAnnotationComponent component in currentList)
{
component.ModifyAttachedAnnotation(attachedAnnotation, previousAttachedAnchor, previousAttachmentLevel); // let the annotation component know
if (component.AttachedAnnotations.Count == 0)
{
// if component decides it can not handle it, remove it
component.PresentationContext.RemoveFromHost(component, true);
}
}
}
else
{
// remove all components
RemoveAttachedAnnotation(attachedAnnotation, true);
// add the new component
AddComponent(attachedAnnotation, newComponent, true);
}
}
}
///
/// Add to the map from attached annotations -> annotation components
///
/// The attached annotation to use as key
/// The component to add to list
private void AddToAttachedAnnotations(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component)
{
Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null");
Debug.Assert(component != null, "component should not be null");
IList currentList;
if (!_attachedAnnotations.TryGetValue(attachedAnnotation, out currentList))
{
currentList = new List();
_attachedAnnotations[attachedAnnotation] = currentList;
}
currentList.Add(component);
}
#endregion Private Methods
#region Private Fields
///
/// Map from attached annotation to list of annotation components.
/// This map contains all attached anntotations the component manager currently knows.
///
private Dictionary> _attachedAnnotations = new Dictionary>();
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
// Copyright(C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// AnnotationComponentManager
//
// History:
// 04/01/2004 axelk: Created AnnotationComponentManager.cs
//
// 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;
namespace MS.Internal.Annotations.Component
{
///
/// Instances of this class manage listen for events from the annotation service and create/remove/modify annotation components in response.
/// Annotation components are created via indirection through an AnnotationComponentChooser which is set in a DP on the app tree.
/// Annotation components are hosted, wrapped inside AnnotationAdorners, in an AdornerLayer respective to the annotated element.
/// Every time an annotation service is instantiated an instance of this class is created.
///
internal class AnnotationComponentManager : DependencyObject
{
#region Constructors
///
/// Return an annotation component manager. If an annotation service is passed in, manager will
/// receive notification from the service. Otherwise it will expect to be called directly.
///
/// optional, annotation service the annotation component manager will register on
internal AnnotationComponentManager(AnnotationService service)
: base()
{
// Only register if a service was passed in. If no service was passed in, we will not receive events.
// This means a client will be calling us directly.
if (service != null)
{
service.AttachedAnnotationChanged += new AttachedAnnotationChangedEventHandler(AttachedAnnotationUpdateEventHandler);
}
}
#endregion Constructors
#region Internal Methods
///
/// The given attached annotation was added by the annotation service
/// Find annotation components for the given attached annotation, maintain
/// mapping from attached annotation to annotation components, and add to the
/// adorner layer if the annotation component is not already in a presentation context.
///
/// Attached annotation to add
/// If true - update components ZOrder after adding the component
internal void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
IAnnotationComponent component = FindComponent(attachedAnnotation);
if (component == null) return;
AddComponent(attachedAnnotation, component, reorder);
}
///
/// The given attached annotation was removed by the annotation service.
/// Find all annotation components and let them know.
/// If an annotation component does not have any other attached annotations, remove it.
/// Update the attachedAnnotations map.
///
/// Attached annotation to remove
/// If true - update components ZOrder after removing the component
internal void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation, bool reorder)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
{
// note, this is not always a bug, since an annotation might have resolved, but no annotation component found
// the tree traversal bug we have currently results in this failing even if annotation components were found, because
// in certain cases annotationService.AttachedAnnotations returns wrong list.
return;
}
IList currentList = _attachedAnnotations[attachedAnnotation];
_attachedAnnotations.Remove(attachedAnnotation); // clean up the map
foreach (IAnnotationComponent component in currentList)
{
component.RemoveAttachedAnnotation(attachedAnnotation); // let the annotation component know
if (component.AttachedAnnotations.Count == 0)
{ // if it has no more attached annotations, remove it
if (component.PresentationContext != null)
component.PresentationContext.RemoveFromHost(component, reorder);
}
}
}
#endregion Internal Methods
#region Private Methods
///
/// Handle the notification coming from the service. Attached annotations can be added, removed, modified.
/// Delegate to appropriate method
///
/// The sender of the event, an annotation service
/// The event arguments containing information on added/deleted/modified attached annotation.
private void AttachedAnnotationUpdateEventHandler(object sender, AttachedAnnotationChangedEventArgs e)
{
switch (e.Action)
{
case AttachedAnnotationAction.Added:
this.AddAttachedAnnotation(e.AttachedAnnotation, true);
break;
case AttachedAnnotationAction.Deleted:
this.RemoveAttachedAnnotation(e.AttachedAnnotation, true);
break;
case AttachedAnnotationAction.Loaded:
this.AddAttachedAnnotation(e.AttachedAnnotation, false);
break;
case AttachedAnnotationAction.Unloaded:
this.RemoveAttachedAnnotation(e.AttachedAnnotation, false);
break;
case AttachedAnnotationAction.AnchorModified:
this.ModifyAttachedAnnotation(e.AttachedAnnotation, e.PreviousAttachedAnchor, e.PreviousAttachmentLevel);
break;
}
}
///
/// given an attachedAnnotation find the chooser attached at its parent
/// and ask it to choose a component suitable to handle the attachedAnnotation
///
/// the attachedAnnotation we are to find a component for
/// an IAnnotationComponent that can handle the attachedAnnotation (or null)
private IAnnotationComponent FindComponent(IAttachedAnnotation attachedAnnotation)
{
Debug.Assert(attachedAnnotation != null, "AttachedAnnotation should not be null");
UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject
Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
AnnotationComponentChooser chooser = AnnotationService.GetChooser(annotatedElement);
// should we return a list instead?
IAnnotationComponent component = chooser.ChooseAnnotationComponent(attachedAnnotation);
return component;
}
///
/// Add an attached annotation to a component and add the component to the adorner layer
/// if the annotation component is not already in a presentation context.
///
/// the attachedAnnotation we are to add to the component
/// the component we are to add to the adorner layer
/// if true - the z-order must be reevaluated
private void AddComponent(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component, bool reorder)
{
UIElement annotatedElement = attachedAnnotation.Parent as UIElement; // casted from DependencyObject
Debug.Assert(annotatedElement != null, "the annotatedElement should inherit from UIElement");
// if annotation component is already in presentation context, nothing else to do
if (component.PresentationContext != null) return;
// otherwise host in the appropriate adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(annotatedElement); // note, GetAdornerLayer requires UIElement
if (layer == null)
{
if (PresentationSource.FromVisual(annotatedElement) == null)
{
// The annotated element is no longer part of the application tree.
// This probably means we are out of [....] - trying to add an annotation
// for an element that has already gone away. Bug # 1580288 tracks
// the need to figure this out.
return;
}
throw new InvalidOperationException(SR.Get(SRID.NoPresentationContextForGivenElement, annotatedElement));
}
// add to the attachedAnnotations
this.AddToAttachedAnnotations(attachedAnnotation, component);
// let the annotation component know about the attached annotation
// call add before adding to adorner layer so the component can be initialized
component.AddAttachedAnnotation(attachedAnnotation); // this might cause recursion in modify if annotation component adds to annotation
AdornerPresentationContext.HostComponent(layer, component, annotatedElement, reorder);
}
///
/// Service indicates attached annotation has changed.
/// For now, take all annotation components maped from old attached annotation and map from new.
/// Then iterate through annotation components to let them know.
/// Note, this needs to change later. If modify is radical, existing component might not want it anymore,
/// and new one might need to be found...
///
/// The modified attached annotation
/// The previous attached anchor for the attached annotation
/// The previous attachment level for the attached annotation
private void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
{
Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null");
Debug.Assert(previousAttachedAnchor != null, "previousAttachedAnchor should not be null");
// if there was no component found for this attached annotation
// then we treat the modify case as an add
if (!_attachedAnnotations.ContainsKey(attachedAnnotation))
{
// this is not necessarily a bug, it can be that the old attached annotation does not have an
// associated annotation component.
this.AddAttachedAnnotation(attachedAnnotation, true);
return;
}
// we have a previous component for this attached annotation
// we find the chooser for the new attached annotation
// and ask it to choose a component
// 1- if it returned null then we just remove the attached annotation
// 2- if it returned a different component, then we treat it as a remove/add
// 3- if it returned the same component then we call ModifyAttachedAnnotation on the component
IAnnotationComponent newComponent = FindComponent(attachedAnnotation);
if (newComponent == null)
{
RemoveAttachedAnnotation(attachedAnnotation, true);
}
else
{
IList currentList = _attachedAnnotations[attachedAnnotation]; //save the current list
// if we found the new component in any of the list of components we already have for this
// attached annotation
if (currentList.Contains(newComponent))
{
// ask the components to handle the anchor modification event
foreach (IAnnotationComponent component in currentList)
{
component.ModifyAttachedAnnotation(attachedAnnotation, previousAttachedAnchor, previousAttachmentLevel); // let the annotation component know
if (component.AttachedAnnotations.Count == 0)
{
// if component decides it can not handle it, remove it
component.PresentationContext.RemoveFromHost(component, true);
}
}
}
else
{
// remove all components
RemoveAttachedAnnotation(attachedAnnotation, true);
// add the new component
AddComponent(attachedAnnotation, newComponent, true);
}
}
}
///
/// Add to the map from attached annotations -> annotation components
///
/// The attached annotation to use as key
/// The component to add to list
private void AddToAttachedAnnotations(IAttachedAnnotation attachedAnnotation, IAnnotationComponent component)
{
Debug.Assert(attachedAnnotation != null, "attachedAnnotation should not be null");
Debug.Assert(component != null, "component should not be null");
IList currentList;
if (!_attachedAnnotations.TryGetValue(attachedAnnotation, out currentList))
{
currentList = new List();
_attachedAnnotations[attachedAnnotation] = currentList;
}
currentList.Add(component);
}
#endregion Private Methods
#region Private Fields
///
/// Map from attached annotation to list of annotation components.
/// This map contains all attached anntotations the component manager currently knows.
///
private Dictionary> _attachedAnnotations = new Dictionary>();
#endregion Private Fields
}
}
// 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
- ThreadInterruptedException.cs
- PreviewPageInfo.cs
- Label.cs
- AccessibilityApplicationManager.cs
- XamlDesignerSerializationManager.cs
- StringBuilder.cs
- MsmqActivation.cs
- FilteredXmlReader.cs
- ProcessManager.cs
- IBuiltInEvidence.cs
- IsolatedStorageFile.cs
- EpmCustomContentWriterNodeData.cs
- TemplatePartAttribute.cs
- StylusTip.cs
- FieldTemplateFactory.cs
- BamlLocalizationDictionary.cs
- _ScatterGatherBuffers.cs
- X509CertificateEndpointIdentity.cs
- TextTreeDeleteContentUndoUnit.cs
- AvtEvent.cs
- IncrementalReadDecoders.cs
- TreeNodeSelectionProcessor.cs
- NamedPermissionSet.cs
- RC2CryptoServiceProvider.cs
- NewExpression.cs
- QueryContinueDragEvent.cs
- SqlLiftWhereClauses.cs
- MessagePropertyFilter.cs
- AutomationPropertyInfo.cs
- Error.cs
- WebPartManagerInternals.cs
- SQLConvert.cs
- filewebrequest.cs
- RedirectionProxy.cs
- SmtpException.cs
- AsymmetricAlgorithm.cs
- Path.cs
- BuildManagerHost.cs
- Cast.cs
- AdornerHitTestResult.cs
- ConfigXmlAttribute.cs
- XamlInt32CollectionSerializer.cs
- EntityDataSourceContextCreatingEventArgs.cs
- PeerApplicationLaunchInfo.cs
- ConnectionPointCookie.cs
- VideoDrawing.cs
- BitmapEffectGeneralTransform.cs
- GiveFeedbackEventArgs.cs
- SqlDuplicator.cs
- BoundField.cs
- StylusPointPropertyInfo.cs
- BypassElementCollection.cs
- SqlException.cs
- ActivityInterfaces.cs
- MetaColumn.cs
- XmlWriter.cs
- ObjectDataProvider.cs
- SecurityRuntime.cs
- ThicknessAnimationBase.cs
- CacheHelper.cs
- SR.cs
- XamlFilter.cs
- FormatConvertedBitmap.cs
- QueryOptionExpression.cs
- SoapEnvelopeProcessingElement.cs
- XsltException.cs
- DynamicDataResources.Designer.cs
- ActionFrame.cs
- RuntimeHelpers.cs
- XamlContextStack.cs
- RolePrincipal.cs
- HttpRequest.cs
- PersonalizationProviderHelper.cs
- MostlySingletonList.cs
- NamedServiceModelExtensionCollectionElement.cs
- EventSinkHelperWriter.cs
- InputGestureCollection.cs
- BasicKeyConstraint.cs
- BinaryObjectReader.cs
- EditorPartDesigner.cs
- AddInAttribute.cs
- DesignerActionUI.cs
- InvokeWebServiceDesigner.cs
- StateDesigner.LayoutSelectionGlyph.cs
- CleanUpVirtualizedItemEventArgs.cs
- FontFamilyConverter.cs
- SqlDataSourceStatusEventArgs.cs
- XmlSerializationReader.cs
- DataServiceProviderMethods.cs
- CachedFontFace.cs
- PKCS1MaskGenerationMethod.cs
- WebPartManagerInternals.cs
- ArraySet.cs
- ManageRequest.cs
- ContentIterators.cs
- WebHttpSecurity.cs
- BasePattern.cs
- DragAssistanceManager.cs
- ListParagraph.cs
- DbCommandTree.cs