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
- MethodImplAttribute.cs
- HttpGetServerProtocol.cs
- SqlCacheDependency.cs
- HtmlControlPersistable.cs
- Vector3DCollectionConverter.cs
- BinaryReader.cs
- CachedPathData.cs
- WebPartDisplayModeEventArgs.cs
- MethodSet.cs
- EllipseGeometry.cs
- ProgressBarRenderer.cs
- CalendarTable.cs
- System.Data_BID.cs
- Int32EqualityComparer.cs
- XmlHierarchyData.cs
- HtmlControlDesigner.cs
- SyndicationDeserializer.cs
- RealizationDrawingContextWalker.cs
- RuleProcessor.cs
- DataGrid.cs
- WindowsScrollBarBits.cs
- ResourceAssociationSetEnd.cs
- TabItemWrapperAutomationPeer.cs
- WindowsNonControl.cs
- PrinterResolution.cs
- WmpBitmapDecoder.cs
- GACMembershipCondition.cs
- ClientData.cs
- TrackingMemoryStream.cs
- EndpointAddress.cs
- ToolStripSeparator.cs
- ProfileBuildProvider.cs
- ExpressionBindings.cs
- EmptyEnumerator.cs
- JsonQNameDataContract.cs
- SqlServices.cs
- FixedSOMPageConstructor.cs
- IsolatedStorageFilePermission.cs
- RectAnimationUsingKeyFrames.cs
- EntityWithChangeTrackerStrategy.cs
- RelationshipType.cs
- OleDbCommand.cs
- EntityClassGenerator.cs
- MeasurementDCInfo.cs
- DoubleLinkListEnumerator.cs
- MsmqIntegrationValidationBehavior.cs
- JsonReaderWriterFactory.cs
- SqlHelper.cs
- ReachDocumentSequenceSerializer.cs
- Queue.cs
- Screen.cs
- HelpKeywordAttribute.cs
- XmlDocumentSchema.cs
- SID.cs
- SqlWriter.cs
- ListGeneralPage.cs
- DataGridHeaderBorder.cs
- OleDbParameterCollection.cs
- MetadataPropertyAttribute.cs
- ProjectionCamera.cs
- BufferBuilder.cs
- DependencyPropertyKind.cs
- SoapIncludeAttribute.cs
- MobileDeviceCapabilitiesSectionHandler.cs
- SinglePageViewer.cs
- _ContextAwareResult.cs
- Object.cs
- BuildManager.cs
- ImageUrlEditor.cs
- SocketPermission.cs
- HttpModuleActionCollection.cs
- GeneralTransform3DTo2D.cs
- PointUtil.cs
- WorkflowMarkupElementEventArgs.cs
- _ScatterGatherBuffers.cs
- TrustManagerMoreInformation.cs
- BreakRecordTable.cs
- NullRuntimeConfig.cs
- BreadCrumbTextConverter.cs
- Stack.cs
- GifBitmapEncoder.cs
- ChannelAcceptor.cs
- ServiceElement.cs
- As.cs
- WindowProviderWrapper.cs
- XmlElementCollection.cs
- StringFunctions.cs
- RemoteWebConfigurationHost.cs
- ListViewInsertionMark.cs
- SharedPerformanceCounter.cs
- ExclusiveTcpListener.cs
- DBBindings.cs
- BookmarkUndoUnit.cs
- Subtree.cs
- AssemblyCollection.cs
- CultureTable.cs
- XmlBinaryReaderSession.cs
- DelayedRegex.cs
- MbpInfo.cs
- ConditionalBranch.cs