Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / PopupRoot.cs / 1305600 / PopupRoot.cs
using System;
using System.Collections;
using System.Windows.Threading;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Markup;
using System.Runtime.InteropServices;
using MS.Utility;
using MS.Win32;
using MS.Internal;
using MS.Internal.Data;
using MS.Internal.KnownBoxes;
namespace System.Windows.Controls.Primitives
{
///
/// The root element inside a popup.
///
internal sealed class PopupRoot : FrameworkElement
{
#region Constructors
static PopupRoot()
{
SnapsToDevicePixelsProperty.OverrideMetadata(typeof(PopupRoot), new FrameworkPropertyMetadata(BooleanBoxes.TrueBox));
}
///
/// Default constructor
///
internal PopupRoot() : base()
{
Initialize();
}
private void Initialize()
{
// Popup root has a decorator used for
// applying the transforms
_transformDecorator = new Decorator();
AddVisualChild(_transformDecorator);
// Clip so animations do not extend beyond its bounds
_transformDecorator.ClipToBounds = true;
// Under the transfrom decorator is an Adorner
// decorator that handles rendering adorners
// and the animated popup translations
_adornerDecorator = new NonLogicalAdornerDecorator();
_transformDecorator.Child = _adornerDecorator;
}
#endregion
#region Visual Children
///
/// Returns the Visual children count.
///
protected override int VisualChildrenCount
{
get { return 1; }
}
///
/// Returns the child at the specified index.
///
protected override Visual GetVisualChild(int index)
{
if (index != 0)
{
throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange));
}
return _transformDecorator;
}
#endregion
#region Automation
///
/// Creates AutomationPeer ( )
///
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
return new System.Windows.Automation.Peers.PopupRootAutomationPeer(this);
}
#endregion Automation
#region Properties
internal UIElement Child
{
get
{
return _adornerDecorator.Child;
}
set
{
_adornerDecorator.Child = value;
}
}
internal Vector AnimationOffset
{
get
{
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform != null)
{
return new Vector(transform.X, transform.Y);
}
return new Vector();
}
}
///
/// This is the transform matrix that the popup content "inherits" from the placement target.
///
internal Transform Transform
{
set
{
_transformDecorator.LayoutTransform = value;
}
}
#endregion
#region Layout
///
/// Invoked when remeasuring the control is required.
///
/// The control cannot return a size larger than the constraint.
/// The size of the child restricted to 75% of screen
protected override Size MeasureOverride(Size constraint)
{
// Measure with no constraints to see how big the content wants to be.
Size desiredSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);
_transformDecorator.Measure(desiredSize);
desiredSize = _transformDecorator.DesiredSize;
Popup popup = Parent as Popup;
if (popup != null)
{
// If the parent is a Popup, then the desired size may need to be restricted to satisfy placement constraints.
bool restrictWidth;
bool restrictHeight;
Size restrictedSize = GetPopupSizeRestrictions(popup, desiredSize, out restrictWidth, out restrictHeight);
// If no restrictions are needed, fall through & use the original desired size.
if (restrictWidth || restrictHeight)
{
if (restrictWidth == restrictHeight)
{
// If we need to restrict in both dimensions, re-measure at the restricted size & use the result as our desiredSize.
desiredSize = Get2DRestrictedDesiredSize(restrictedSize);
}
else
{
// If we need to restrict in only one dimension, re-measure with no constraint on the other dimension.
// This will give the content a chance to wrap.
Size restricted1DDesiredSize = new Size(restrictWidth ? restrictedSize.Width : Double.PositiveInfinity,
restrictHeight ? restrictedSize.Height : Double.PositiveInfinity);
_transformDecorator.Measure(restricted1DDesiredSize);
desiredSize = _transformDecorator.DesiredSize;
// Restricting in one dimension may increase the size in the other dimension, so we need to restrict again
// to satisfy placement constraints.
restrictedSize = GetPopupSizeRestrictions(popup, desiredSize, out restrictWidth, out restrictHeight);
if (restrictWidth || restrictHeight)
{
// If a restriction is still in place, we cannot satisfy both desiredSize and placement constraints,
// so respect the placement constraints & clip the content.
desiredSize = Get2DRestrictedDesiredSize(restrictedSize);
}
}
}
}
return desiredSize;
}
///
/// Gets teh restricted size of a popup & computes which dimensions were affected.
///
private Size GetPopupSizeRestrictions(Popup popup, Size desiredSize, out bool restrictWidth, out bool restrictHeight)
{
Size restrictedSize = popup.RestrictSize(desiredSize);
restrictWidth = Math.Abs(restrictedSize.Width - desiredSize.Width) > Popup.Tolerance;
restrictHeight = Math.Abs(restrictedSize.Height - desiredSize.Height) > Popup.Tolerance;
return restrictedSize;
}
///
/// Measures the _transformDecorator at the restricted size to determine a new desired size.
///
private Size Get2DRestrictedDesiredSize(Size restrictedSize)
{
_transformDecorator.Measure(restrictedSize);
Size restricted2DDesiredSize = _transformDecorator.DesiredSize;
return new Size(Math.Min(restrictedSize.Width, restricted2DDesiredSize.Width),
Math.Min(restrictedSize.Height, restricted2DDesiredSize.Height));
}
///
/// ArrangeOverride allows for the customization of the positioning of children.
///
/// The final size that element should use to arrange itself and its children.
protected override Size ArrangeOverride(Size arrangeSize)
{
_transformDecorator.Arrange(new Rect(arrangeSize));
return arrangeSize;
}
///
/// Sets up bindings between (Min/Max)Width/Height properties on Popup and PopupRoot.
///
/// The parent Popup.
internal void SetupLayoutBindings(Popup popup)
{
Binding binding = new Binding("Width");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(WidthProperty, binding);
binding = new Binding("Height");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(HeightProperty, binding);
binding = new Binding("MinWidth");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MinWidthProperty, binding);
binding = new Binding("MinHeight");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MinHeightProperty, binding);
binding = new Binding("MaxWidth");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MaxWidthProperty, binding);
binding = new Binding("MaxHeight");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MaxHeightProperty, binding);
}
// Popup is transparent, change opacity of root
internal void SetupFadeAnimation(Duration duration, bool visible)
{
DoubleAnimation anim = new DoubleAnimation(visible ? 0.0 : 1.0, visible ? 1.0 : 0.0, duration, FillBehavior.HoldEnd);
BeginAnimation(PopupRoot.OpacityProperty, anim);
}
// Popup is transparent, we can leave popup size alone
// and animate the translation of the popup
internal void SetupTranslateAnimations(PopupAnimation animationType, Duration duration, bool animateFromRight, bool animateFromBottom)
{
UIElement child = Child;
if (child == null)
return;
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform == null)
{
transform = new TranslateTransform();
_adornerDecorator.RenderTransform = transform;
}
if (animationType == PopupAnimation.Scroll)
{
// If the flow direction of the child is different than ours, animate in opposite direction
FlowDirection childFlowDirection = (FlowDirection)child.GetValue(FlowDirectionProperty);
FlowDirection thisFlowDirection = FlowDirection;
if (childFlowDirection != thisFlowDirection)
{
animateFromRight = !animateFromRight;
}
double width = _adornerDecorator.RenderSize.Width;
DoubleAnimation xAnim = new DoubleAnimation(animateFromRight ? width : -width, 0.0, duration, FillBehavior.Stop);
transform.BeginAnimation(TranslateTransform.XProperty, xAnim);
}
double height = _adornerDecorator.RenderSize.Height;
DoubleAnimation yAnim = new DoubleAnimation(animateFromBottom ? height : -height, 0.0, duration, FillBehavior.Stop);
transform.BeginAnimation(TranslateTransform.YProperty, yAnim);
}
// Clear animations on this and _adorner
internal void StopAnimations()
{
BeginAnimation(PopupRoot.OpacityProperty, null);
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform != null)
{
transform.BeginAnimation(TranslateTransform.XProperty, null);
transform.BeginAnimation(TranslateTransform.YProperty, null);
}
}
#endregion
#region Tree Overrides
internal override bool IgnoreModelParentBuildRoute(RoutedEventArgs e)
{
// We do not want QueryCursor event to bubble up past this node
if(e is QueryCursorEventArgs)
{
return true;
}
// Defer to the child to determine if we should route events up the logical tree.
FrameworkElement child = Child as FrameworkElement;
if(child != null)
{
return child.IgnoreModelParentBuildRoute(e);
}
else
{
return base.IgnoreModelParentBuildRoute(e);
}
}
#endregion
#region Data
private Decorator _transformDecorator; // The decorator used to apply animations
private AdornerDecorator _adornerDecorator;
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections;
using System.Windows.Threading;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Markup;
using System.Runtime.InteropServices;
using MS.Utility;
using MS.Win32;
using MS.Internal;
using MS.Internal.Data;
using MS.Internal.KnownBoxes;
namespace System.Windows.Controls.Primitives
{
///
/// The root element inside a popup.
///
internal sealed class PopupRoot : FrameworkElement
{
#region Constructors
static PopupRoot()
{
SnapsToDevicePixelsProperty.OverrideMetadata(typeof(PopupRoot), new FrameworkPropertyMetadata(BooleanBoxes.TrueBox));
}
///
/// Default constructor
///
internal PopupRoot() : base()
{
Initialize();
}
private void Initialize()
{
// Popup root has a decorator used for
// applying the transforms
_transformDecorator = new Decorator();
AddVisualChild(_transformDecorator);
// Clip so animations do not extend beyond its bounds
_transformDecorator.ClipToBounds = true;
// Under the transfrom decorator is an Adorner
// decorator that handles rendering adorners
// and the animated popup translations
_adornerDecorator = new NonLogicalAdornerDecorator();
_transformDecorator.Child = _adornerDecorator;
}
#endregion
#region Visual Children
///
/// Returns the Visual children count.
///
protected override int VisualChildrenCount
{
get { return 1; }
}
///
/// Returns the child at the specified index.
///
protected override Visual GetVisualChild(int index)
{
if (index != 0)
{
throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange));
}
return _transformDecorator;
}
#endregion
#region Automation
///
/// Creates AutomationPeer ( )
///
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
return new System.Windows.Automation.Peers.PopupRootAutomationPeer(this);
}
#endregion Automation
#region Properties
internal UIElement Child
{
get
{
return _adornerDecorator.Child;
}
set
{
_adornerDecorator.Child = value;
}
}
internal Vector AnimationOffset
{
get
{
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform != null)
{
return new Vector(transform.X, transform.Y);
}
return new Vector();
}
}
///
/// This is the transform matrix that the popup content "inherits" from the placement target.
///
internal Transform Transform
{
set
{
_transformDecorator.LayoutTransform = value;
}
}
#endregion
#region Layout
///
/// Invoked when remeasuring the control is required.
///
/// The control cannot return a size larger than the constraint.
/// The size of the child restricted to 75% of screen
protected override Size MeasureOverride(Size constraint)
{
// Measure with no constraints to see how big the content wants to be.
Size desiredSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);
_transformDecorator.Measure(desiredSize);
desiredSize = _transformDecorator.DesiredSize;
Popup popup = Parent as Popup;
if (popup != null)
{
// If the parent is a Popup, then the desired size may need to be restricted to satisfy placement constraints.
bool restrictWidth;
bool restrictHeight;
Size restrictedSize = GetPopupSizeRestrictions(popup, desiredSize, out restrictWidth, out restrictHeight);
// If no restrictions are needed, fall through & use the original desired size.
if (restrictWidth || restrictHeight)
{
if (restrictWidth == restrictHeight)
{
// If we need to restrict in both dimensions, re-measure at the restricted size & use the result as our desiredSize.
desiredSize = Get2DRestrictedDesiredSize(restrictedSize);
}
else
{
// If we need to restrict in only one dimension, re-measure with no constraint on the other dimension.
// This will give the content a chance to wrap.
Size restricted1DDesiredSize = new Size(restrictWidth ? restrictedSize.Width : Double.PositiveInfinity,
restrictHeight ? restrictedSize.Height : Double.PositiveInfinity);
_transformDecorator.Measure(restricted1DDesiredSize);
desiredSize = _transformDecorator.DesiredSize;
// Restricting in one dimension may increase the size in the other dimension, so we need to restrict again
// to satisfy placement constraints.
restrictedSize = GetPopupSizeRestrictions(popup, desiredSize, out restrictWidth, out restrictHeight);
if (restrictWidth || restrictHeight)
{
// If a restriction is still in place, we cannot satisfy both desiredSize and placement constraints,
// so respect the placement constraints & clip the content.
desiredSize = Get2DRestrictedDesiredSize(restrictedSize);
}
}
}
}
return desiredSize;
}
///
/// Gets teh restricted size of a popup & computes which dimensions were affected.
///
private Size GetPopupSizeRestrictions(Popup popup, Size desiredSize, out bool restrictWidth, out bool restrictHeight)
{
Size restrictedSize = popup.RestrictSize(desiredSize);
restrictWidth = Math.Abs(restrictedSize.Width - desiredSize.Width) > Popup.Tolerance;
restrictHeight = Math.Abs(restrictedSize.Height - desiredSize.Height) > Popup.Tolerance;
return restrictedSize;
}
///
/// Measures the _transformDecorator at the restricted size to determine a new desired size.
///
private Size Get2DRestrictedDesiredSize(Size restrictedSize)
{
_transformDecorator.Measure(restrictedSize);
Size restricted2DDesiredSize = _transformDecorator.DesiredSize;
return new Size(Math.Min(restrictedSize.Width, restricted2DDesiredSize.Width),
Math.Min(restrictedSize.Height, restricted2DDesiredSize.Height));
}
///
/// ArrangeOverride allows for the customization of the positioning of children.
///
/// The final size that element should use to arrange itself and its children.
protected override Size ArrangeOverride(Size arrangeSize)
{
_transformDecorator.Arrange(new Rect(arrangeSize));
return arrangeSize;
}
///
/// Sets up bindings between (Min/Max)Width/Height properties on Popup and PopupRoot.
///
/// The parent Popup.
internal void SetupLayoutBindings(Popup popup)
{
Binding binding = new Binding("Width");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(WidthProperty, binding);
binding = new Binding("Height");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(HeightProperty, binding);
binding = new Binding("MinWidth");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MinWidthProperty, binding);
binding = new Binding("MinHeight");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MinHeightProperty, binding);
binding = new Binding("MaxWidth");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MaxWidthProperty, binding);
binding = new Binding("MaxHeight");
binding.Mode = BindingMode.OneWay;
binding.Source = popup;
_adornerDecorator.SetBinding(MaxHeightProperty, binding);
}
// Popup is transparent, change opacity of root
internal void SetupFadeAnimation(Duration duration, bool visible)
{
DoubleAnimation anim = new DoubleAnimation(visible ? 0.0 : 1.0, visible ? 1.0 : 0.0, duration, FillBehavior.HoldEnd);
BeginAnimation(PopupRoot.OpacityProperty, anim);
}
// Popup is transparent, we can leave popup size alone
// and animate the translation of the popup
internal void SetupTranslateAnimations(PopupAnimation animationType, Duration duration, bool animateFromRight, bool animateFromBottom)
{
UIElement child = Child;
if (child == null)
return;
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform == null)
{
transform = new TranslateTransform();
_adornerDecorator.RenderTransform = transform;
}
if (animationType == PopupAnimation.Scroll)
{
// If the flow direction of the child is different than ours, animate in opposite direction
FlowDirection childFlowDirection = (FlowDirection)child.GetValue(FlowDirectionProperty);
FlowDirection thisFlowDirection = FlowDirection;
if (childFlowDirection != thisFlowDirection)
{
animateFromRight = !animateFromRight;
}
double width = _adornerDecorator.RenderSize.Width;
DoubleAnimation xAnim = new DoubleAnimation(animateFromRight ? width : -width, 0.0, duration, FillBehavior.Stop);
transform.BeginAnimation(TranslateTransform.XProperty, xAnim);
}
double height = _adornerDecorator.RenderSize.Height;
DoubleAnimation yAnim = new DoubleAnimation(animateFromBottom ? height : -height, 0.0, duration, FillBehavior.Stop);
transform.BeginAnimation(TranslateTransform.YProperty, yAnim);
}
// Clear animations on this and _adorner
internal void StopAnimations()
{
BeginAnimation(PopupRoot.OpacityProperty, null);
TranslateTransform transform = _adornerDecorator.RenderTransform as TranslateTransform;
if (transform != null)
{
transform.BeginAnimation(TranslateTransform.XProperty, null);
transform.BeginAnimation(TranslateTransform.YProperty, null);
}
}
#endregion
#region Tree Overrides
internal override bool IgnoreModelParentBuildRoute(RoutedEventArgs e)
{
// We do not want QueryCursor event to bubble up past this node
if(e is QueryCursorEventArgs)
{
return true;
}
// Defer to the child to determine if we should route events up the logical tree.
FrameworkElement child = Child as FrameworkElement;
if(child != null)
{
return child.IgnoreModelParentBuildRoute(e);
}
else
{
return base.IgnoreModelParentBuildRoute(e);
}
}
#endregion
#region Data
private Decorator _transformDecorator; // The decorator used to apply animations
private AdornerDecorator _adornerDecorator;
#endregion
}
}
// 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
- MergablePropertyAttribute.cs
- RowSpanVector.cs
- _FixedSizeReader.cs
- BoolExpressionVisitors.cs
- ColorDialog.cs
- NavigationProgressEventArgs.cs
- VBCodeProvider.cs
- TimersDescriptionAttribute.cs
- ListenerElementsCollection.cs
- EditingCommands.cs
- CharAnimationBase.cs
- InstalledFontCollection.cs
- MappableObjectManager.cs
- ResourceProviderFactory.cs
- XmlSchemaIdentityConstraint.cs
- ExecutionContext.cs
- VirtualDirectoryMappingCollection.cs
- XmlNamedNodeMap.cs
- DbConnectionPool.cs
- AccessViolationException.cs
- ChildrenQuery.cs
- OperationContext.cs
- SelectedCellsCollection.cs
- QuadraticBezierSegment.cs
- StorageComplexTypeMapping.cs
- MarshalByRefObject.cs
- PersistenceTypeAttribute.cs
- CreateUserWizardStep.cs
- LocalizedNameDescriptionPair.cs
- VariantWrapper.cs
- ChannelProtectionRequirements.cs
- ProcessHostFactoryHelper.cs
- WebEventTraceProvider.cs
- Effect.cs
- DataGridViewTextBoxCell.cs
- FrameworkTextComposition.cs
- Listbox.cs
- ToolStripKeyboardHandlingService.cs
- GridLength.cs
- HttpWebRequestElement.cs
- ConnectionInterfaceCollection.cs
- TreeViewItemAutomationPeer.cs
- GraphicsState.cs
- SoapHeaders.cs
- CodeMemberField.cs
- ConfigurationSectionGroup.cs
- SqlProcedureAttribute.cs
- StylusLogic.cs
- ExpressionBuilderCollection.cs
- WindowsListBox.cs
- NavigationEventArgs.cs
- HandlerBase.cs
- ItemAutomationPeer.cs
- propertyentry.cs
- FixedSOMTableCell.cs
- FrameworkReadOnlyPropertyMetadata.cs
- TransformerInfo.cs
- WebFormDesignerActionService.cs
- ISSmlParser.cs
- MultiPageTextView.cs
- BooleanExpr.cs
- DesignBindingEditor.cs
- EtwTrace.cs
- SerializationHelper.cs
- FontDifferentiator.cs
- Int64AnimationUsingKeyFrames.cs
- BrowserDefinitionCollection.cs
- BlockCollection.cs
- ObservableCollection.cs
- Registry.cs
- FillRuleValidation.cs
- ACL.cs
- Matrix.cs
- CustomPopupPlacement.cs
- XNameConverter.cs
- TargetControlTypeAttribute.cs
- DebugInfoExpression.cs
- BitHelper.cs
- CompiledIdentityConstraint.cs
- Polyline.cs
- EntityStoreSchemaFilterEntry.cs
- Domain.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- DataGridAutoGeneratingColumnEventArgs.cs
- ScriptModule.cs
- WmlLiteralTextAdapter.cs
- HTTPNotFoundHandler.cs
- _IPv4Address.cs
- IgnoreFileBuildProvider.cs
- messageonlyhwndwrapper.cs
- SessionPageStateSection.cs
- CompilerHelpers.cs
- URIFormatException.cs
- XmlConverter.cs
- XPathNodeIterator.cs
- ServiceDurableInstance.cs
- DispatcherExceptionEventArgs.cs
- ConfigurationManagerInternalFactory.cs
- PositiveTimeSpanValidatorAttribute.cs
- FrameworkElementAutomationPeer.cs