PopupRoot.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / 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.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK