DockPanel.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / DockPanel.cs / 1 / DockPanel.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// File: DockPanel.cs 
//
// Description: Contains the DockPanel class. 
//              Spec at http://avalon/layout/Specs/DockPanel.xml 
//
// History: 
//  06/11/2003 : greglett  - Added to WCP branch (was Stack.cs in old branch)
//
//---------------------------------------------------------------------------
 
using MS.Internal;
using MS.Internal.PresentationFramework; 
using MS.Utility; 
using System.Diagnostics;
using System.Windows.Threading; 

using System.Windows.Media;

using System; 

namespace System.Windows.Controls 
{ 

    #region Dock enum type 

    /// 
    /// Dock - Enum which describes how to position and stretch the child of a DockPanel.
    ///  
    /// 
    public enum Dock 
    { 
        /// 
        /// Position this child at the left of the remaining space. 
        /// 
        Left,

        ///  
        /// Position this child at the top of the remaining space.
        ///  
        Top, 

        ///  
        /// Position this child at the right of the remaining space.
        /// 
        Right,
 
        /// 
        /// Position this child at the bottom of the remaining space. 
        ///  
        Bottom,
    } 

    #endregion

    ///  
    /// DockPanel is used to size and position children inward from the edges of available space.
    /// 
    /// A  enum (see  and ) 
    /// determines on which size a child is placed.  Children are stacked in order from these edges until
    /// there is no more space; this happens when previous children have consumed all available space, or a child 
    /// with Dock set to Fill is encountered.
    /// 
    public class DockPanel : Panel
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------------------- 

        #region Constructors

        ///  
        ///     Default DependencyObject constructor
        ///  
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance. 
        /// 
        public DockPanel() : base()
        {
        } 

        #endregion 
 
        //--------------------------------------------------------------------
        // 
        //  Public Methods
        //
        //-------------------------------------------------------------------
 
        #region Public Methods
 
        ///  
        /// Reads the attached property Dock from the given element.
        ///  
        /// UIElement from which to read the attached property.
        /// The property's value.
        /// 
        [AttachedPropertyBrowsableForChildren()] 
        public static Dock GetDock(UIElement element)
        { 
            if (element == null) { throw new ArgumentNullException("element"); } 

            return (Dock) element.GetValue(DockProperty); 
        }

        /// 
        /// Writes the attached property Dock to the given element. 
        /// 
        /// UIElement to which to write the attached property. 
        /// The property value to set 
        /// 
        public static void SetDock(UIElement element, Dock dock) 
        {
            if (element == null) { throw new ArgumentNullException("element"); }

            element.SetValue(DockProperty, dock); 
        }
 
        private static void OnDockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            UIElement uie = d as UIElement; //it may be anyting, like FlowDocument... bug 1237275 
            if(uie != null)
            {
                DockPanel p = VisualTreeHelper.GetParent(uie) as DockPanel;
                if(p != null) 
                {
                    p.InvalidateMeasure(); 
                } 
            }
        } 

        #endregion

        //-------------------------------------------------------------------- 
        //
        //  Public Properties + Dependency Properties's 
        // 
        //--------------------------------------------------------------------
 
        #region Public Properties

        /// 
        /// This property controls whether the last child in the DockPanel should be stretched to fill any 
        /// remaining available space.
        ///  
        public bool LastChildFill 
        {
            get { return (bool) GetValue(LastChildFillProperty); } 
            set { SetValue(LastChildFillProperty, value); }
        }

 
        /// 
        /// DependencyProperty for  property. 
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty LastChildFillProperty = 
                DependencyProperty.Register(
                        "LastChildFill",
                        typeof(bool),
                        typeof(DockPanel), 
                        new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsArrange));
 
 
        /// 
        /// DependencyProperty for Dock property. 
        /// 
        /// 
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty DockProperty =
                DependencyProperty.RegisterAttached( 
                        "Dock", 
                        typeof(Dock),
                        typeof(DockPanel), 
                        new FrameworkPropertyMetadata(
                            Dock.Left,
                            new PropertyChangedCallback(OnDockChanged)),
                        new ValidateValueCallback(IsValidDock)); 

        #endregion 
 
        //-------------------------------------------------------------------
        // 
        //  Protected Methods
        //
        //--------------------------------------------------------------------
 
        #region Protected Methods
 
        ///  
        /// Updates DesiredSize of the DockPanel.  Called by parent UIElement.  This is the first pass of layout.
        ///  
        /// 
        /// Children are measured based on their sizing properties and .
        /// Each child is allowed to consume all of the space on the side on which it is docked; Left/Right docked
        /// children are granted all vertical space for their entire width, and Top/Bottom docked children are 
        /// granted all horizontal space for their entire height.
        ///  
        /// Constraint size is an "upper limit" that the return value should not exceed. 
        /// The Panel's desired size.
        protected override Size MeasureOverride(Size constraint) 
        {
            UIElementCollection children = InternalChildren;

            double parentWidth       = 0;   // Our current required width due to children thus far. 
            double parentHeight      = 0;   // Our current required height due to children thus far.
            double accumulatedWidth  = 0;   // Total width consumed by children. 
            double accumulatedHeight = 0;   // Total height consumed by children. 

            for (int i = 0, count = children.Count; i < count; ++i) 
            {
                UIElement child = children[i];
                Size   childConstraint;             // Contains the suggested input constraint for this child.
                Size   childDesiredSize;            // Contains the return size from child measure. 

                if (child == null) { continue; } 
 
                // Child constraint is the remaining size; this is total size minus size consumed by previous children.
                childConstraint = new Size(Math.Max(0.0, constraint.Width - accumulatedWidth), 
                                           Math.Max(0.0, constraint.Height - accumulatedHeight));

                // Measure child.
                child.Measure(childConstraint); 
                childDesiredSize = child.DesiredSize;
 
                // Now, we adjust: 
                // 1. Size consumed by children (accumulatedSize).  This will be used when computing subsequent
                //    children to determine how much space is remaining for them. 
                // 2. Parent size implied by this child (parentSize) when added to the current children (accumulatedSize).
                //    This is different from the size above in one respect: A Dock.Left child implies a height, but does
                //    not actually consume any height for subsequent children.
                // If we accumulate size in a given dimension, the next child (or the end conditions after the child loop) 
                // will deal with computing our minimum size (parentSize) due to that accumulation.
                // Therefore, we only need to compute our minimum size (parentSize) in dimensions that this child does 
                //   not accumulate: Width for Top/Bottom, Height for Left/Right. 
                switch (DockPanel.GetDock(child))
                { 
                    case Dock.Left:
                    case Dock.Right:
                        parentHeight = Math.Max(parentHeight, accumulatedHeight + childDesiredSize.Height);
                        accumulatedWidth += childDesiredSize.Width; 
                        break;
 
                    case Dock.Top: 
                    case Dock.Bottom:
                        parentWidth = Math.Max(parentWidth, accumulatedWidth + childDesiredSize.Width); 
                        accumulatedHeight += childDesiredSize.Height;
                        break;
                }
            } 

            // Make sure the final accumulated size is reflected in parentSize. 
            parentWidth = Math.Max(parentWidth, accumulatedWidth); 
            parentHeight = Math.Max(parentHeight, accumulatedHeight);
 
            return (new Size(parentWidth, parentHeight));
        }

        ///  
        /// DockPanel computes a position and final size for each of its children based upon their
        ///  enum and sizing properties. 
        ///  
        /// Size that DockPanel will assume to position children.
        protected override Size ArrangeOverride(Size arrangeSize) 
        {
            UIElementCollection children = InternalChildren;
            int totalChildrenCount = children.Count;
            int nonFillChildrenCount = totalChildrenCount - (LastChildFill ? 1 : 0); 

            double accumulatedLeft   = 0; 
            double accumulatedTop    = 0; 
            double accumulatedRight  = 0;
            double accumulatedBottom = 0; 

            for (int i = 0; i < totalChildrenCount; ++i)
            {
                UIElement child = children[i]; 
                if (child == null) { continue; }
 
                Size childDesiredSize = child.DesiredSize; 
                Rect rcChild = new Rect(
                    accumulatedLeft, 
                    accumulatedTop,
                    Math.Max(0.0, arrangeSize.Width - (accumulatedLeft + accumulatedRight)),
                    Math.Max(0.0, arrangeSize.Height - (accumulatedTop + accumulatedBottom))    );
 
                if (i < nonFillChildrenCount)
                { 
                    switch (DockPanel.GetDock(child)) 
                    {
                        case Dock.Left: 
                            accumulatedLeft += childDesiredSize.Width;
                            rcChild.Width = childDesiredSize.Width;
                            break;
 
                        case Dock.Right:
                            accumulatedRight += childDesiredSize.Width; 
                            rcChild.X = Math.Max(0.0, arrangeSize.Width - accumulatedRight); 
                            rcChild.Width = childDesiredSize.Width;
                            break; 

                        case Dock.Top:
                            accumulatedTop += childDesiredSize.Height;
                            rcChild.Height = childDesiredSize.Height; 
                            break;
 
                        case Dock.Bottom: 
                            accumulatedBottom += childDesiredSize.Height;
                            rcChild.Y = Math.Max(0.0, arrangeSize.Height - accumulatedBottom); 
                            rcChild.Height = childDesiredSize.Height;
                            break;
                    }
                } 

                child.Arrange(rcChild); 
            } 

            return (arrangeSize); 
        }

        #endregion Protected Methods
 
        //-------------------------------------------------------------------
        // 
        //  Private Methods 
        //
        //------------------------------------------------------------------- 

        #region Private Methods

        internal static bool IsValidDock(object o) 
        {
            Dock dock = (Dock)o; 
 
            return (    dock == Dock.Left
                    ||  dock == Dock.Top 
                    ||  dock == Dock.Right
                    ||  dock == Dock.Bottom);
        }
 
        //
        //  This property 
        //  1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject 
        //  2. This is a performance optimization
        // 
        internal override int EffectiveValuesInitialSize
        {
            get { return 9; }
        } 

        #endregion Private Methods 
 
    }
} 


// 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.
//
// File: DockPanel.cs 
//
// Description: Contains the DockPanel class. 
//              Spec at http://avalon/layout/Specs/DockPanel.xml 
//
// History: 
//  06/11/2003 : greglett  - Added to WCP branch (was Stack.cs in old branch)
//
//---------------------------------------------------------------------------
 
using MS.Internal;
using MS.Internal.PresentationFramework; 
using MS.Utility; 
using System.Diagnostics;
using System.Windows.Threading; 

using System.Windows.Media;

using System; 

namespace System.Windows.Controls 
{ 

    #region Dock enum type 

    /// 
    /// Dock - Enum which describes how to position and stretch the child of a DockPanel.
    ///  
    /// 
    public enum Dock 
    { 
        /// 
        /// Position this child at the left of the remaining space. 
        /// 
        Left,

        ///  
        /// Position this child at the top of the remaining space.
        ///  
        Top, 

        ///  
        /// Position this child at the right of the remaining space.
        /// 
        Right,
 
        /// 
        /// Position this child at the bottom of the remaining space. 
        ///  
        Bottom,
    } 

    #endregion

    ///  
    /// DockPanel is used to size and position children inward from the edges of available space.
    /// 
    /// A  enum (see  and ) 
    /// determines on which size a child is placed.  Children are stacked in order from these edges until
    /// there is no more space; this happens when previous children have consumed all available space, or a child 
    /// with Dock set to Fill is encountered.
    /// 
    public class DockPanel : Panel
    { 
        //-------------------------------------------------------------------
        // 
        //  Constructors 
        //
        //------------------------------------------------------------------- 

        #region Constructors

        ///  
        ///     Default DependencyObject constructor
        ///  
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance. 
        /// 
        public DockPanel() : base()
        {
        } 

        #endregion 
 
        //--------------------------------------------------------------------
        // 
        //  Public Methods
        //
        //-------------------------------------------------------------------
 
        #region Public Methods
 
        ///  
        /// Reads the attached property Dock from the given element.
        ///  
        /// UIElement from which to read the attached property.
        /// The property's value.
        /// 
        [AttachedPropertyBrowsableForChildren()] 
        public static Dock GetDock(UIElement element)
        { 
            if (element == null) { throw new ArgumentNullException("element"); } 

            return (Dock) element.GetValue(DockProperty); 
        }

        /// 
        /// Writes the attached property Dock to the given element. 
        /// 
        /// UIElement to which to write the attached property. 
        /// The property value to set 
        /// 
        public static void SetDock(UIElement element, Dock dock) 
        {
            if (element == null) { throw new ArgumentNullException("element"); }

            element.SetValue(DockProperty, dock); 
        }
 
        private static void OnDockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            UIElement uie = d as UIElement; //it may be anyting, like FlowDocument... bug 1237275 
            if(uie != null)
            {
                DockPanel p = VisualTreeHelper.GetParent(uie) as DockPanel;
                if(p != null) 
                {
                    p.InvalidateMeasure(); 
                } 
            }
        } 

        #endregion

        //-------------------------------------------------------------------- 
        //
        //  Public Properties + Dependency Properties's 
        // 
        //--------------------------------------------------------------------
 
        #region Public Properties

        /// 
        /// This property controls whether the last child in the DockPanel should be stretched to fill any 
        /// remaining available space.
        ///  
        public bool LastChildFill 
        {
            get { return (bool) GetValue(LastChildFillProperty); } 
            set { SetValue(LastChildFillProperty, value); }
        }

 
        /// 
        /// DependencyProperty for  property. 
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty LastChildFillProperty = 
                DependencyProperty.Register(
                        "LastChildFill",
                        typeof(bool),
                        typeof(DockPanel), 
                        new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsArrange));
 
 
        /// 
        /// DependencyProperty for Dock property. 
        /// 
        /// 
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty DockProperty =
                DependencyProperty.RegisterAttached( 
                        "Dock", 
                        typeof(Dock),
                        typeof(DockPanel), 
                        new FrameworkPropertyMetadata(
                            Dock.Left,
                            new PropertyChangedCallback(OnDockChanged)),
                        new ValidateValueCallback(IsValidDock)); 

        #endregion 
 
        //-------------------------------------------------------------------
        // 
        //  Protected Methods
        //
        //--------------------------------------------------------------------
 
        #region Protected Methods
 
        ///  
        /// Updates DesiredSize of the DockPanel.  Called by parent UIElement.  This is the first pass of layout.
        ///  
        /// 
        /// Children are measured based on their sizing properties and .
        /// Each child is allowed to consume all of the space on the side on which it is docked; Left/Right docked
        /// children are granted all vertical space for their entire width, and Top/Bottom docked children are 
        /// granted all horizontal space for their entire height.
        ///  
        /// Constraint size is an "upper limit" that the return value should not exceed. 
        /// The Panel's desired size.
        protected override Size MeasureOverride(Size constraint) 
        {
            UIElementCollection children = InternalChildren;

            double parentWidth       = 0;   // Our current required width due to children thus far. 
            double parentHeight      = 0;   // Our current required height due to children thus far.
            double accumulatedWidth  = 0;   // Total width consumed by children. 
            double accumulatedHeight = 0;   // Total height consumed by children. 

            for (int i = 0, count = children.Count; i < count; ++i) 
            {
                UIElement child = children[i];
                Size   childConstraint;             // Contains the suggested input constraint for this child.
                Size   childDesiredSize;            // Contains the return size from child measure. 

                if (child == null) { continue; } 
 
                // Child constraint is the remaining size; this is total size minus size consumed by previous children.
                childConstraint = new Size(Math.Max(0.0, constraint.Width - accumulatedWidth), 
                                           Math.Max(0.0, constraint.Height - accumulatedHeight));

                // Measure child.
                child.Measure(childConstraint); 
                childDesiredSize = child.DesiredSize;
 
                // Now, we adjust: 
                // 1. Size consumed by children (accumulatedSize).  This will be used when computing subsequent
                //    children to determine how much space is remaining for them. 
                // 2. Parent size implied by this child (parentSize) when added to the current children (accumulatedSize).
                //    This is different from the size above in one respect: A Dock.Left child implies a height, but does
                //    not actually consume any height for subsequent children.
                // If we accumulate size in a given dimension, the next child (or the end conditions after the child loop) 
                // will deal with computing our minimum size (parentSize) due to that accumulation.
                // Therefore, we only need to compute our minimum size (parentSize) in dimensions that this child does 
                //   not accumulate: Width for Top/Bottom, Height for Left/Right. 
                switch (DockPanel.GetDock(child))
                { 
                    case Dock.Left:
                    case Dock.Right:
                        parentHeight = Math.Max(parentHeight, accumulatedHeight + childDesiredSize.Height);
                        accumulatedWidth += childDesiredSize.Width; 
                        break;
 
                    case Dock.Top: 
                    case Dock.Bottom:
                        parentWidth = Math.Max(parentWidth, accumulatedWidth + childDesiredSize.Width); 
                        accumulatedHeight += childDesiredSize.Height;
                        break;
                }
            } 

            // Make sure the final accumulated size is reflected in parentSize. 
            parentWidth = Math.Max(parentWidth, accumulatedWidth); 
            parentHeight = Math.Max(parentHeight, accumulatedHeight);
 
            return (new Size(parentWidth, parentHeight));
        }

        ///  
        /// DockPanel computes a position and final size for each of its children based upon their
        ///  enum and sizing properties. 
        ///  
        /// Size that DockPanel will assume to position children.
        protected override Size ArrangeOverride(Size arrangeSize) 
        {
            UIElementCollection children = InternalChildren;
            int totalChildrenCount = children.Count;
            int nonFillChildrenCount = totalChildrenCount - (LastChildFill ? 1 : 0); 

            double accumulatedLeft   = 0; 
            double accumulatedTop    = 0; 
            double accumulatedRight  = 0;
            double accumulatedBottom = 0; 

            for (int i = 0; i < totalChildrenCount; ++i)
            {
                UIElement child = children[i]; 
                if (child == null) { continue; }
 
                Size childDesiredSize = child.DesiredSize; 
                Rect rcChild = new Rect(
                    accumulatedLeft, 
                    accumulatedTop,
                    Math.Max(0.0, arrangeSize.Width - (accumulatedLeft + accumulatedRight)),
                    Math.Max(0.0, arrangeSize.Height - (accumulatedTop + accumulatedBottom))    );
 
                if (i < nonFillChildrenCount)
                { 
                    switch (DockPanel.GetDock(child)) 
                    {
                        case Dock.Left: 
                            accumulatedLeft += childDesiredSize.Width;
                            rcChild.Width = childDesiredSize.Width;
                            break;
 
                        case Dock.Right:
                            accumulatedRight += childDesiredSize.Width; 
                            rcChild.X = Math.Max(0.0, arrangeSize.Width - accumulatedRight); 
                            rcChild.Width = childDesiredSize.Width;
                            break; 

                        case Dock.Top:
                            accumulatedTop += childDesiredSize.Height;
                            rcChild.Height = childDesiredSize.Height; 
                            break;
 
                        case Dock.Bottom: 
                            accumulatedBottom += childDesiredSize.Height;
                            rcChild.Y = Math.Max(0.0, arrangeSize.Height - accumulatedBottom); 
                            rcChild.Height = childDesiredSize.Height;
                            break;
                    }
                } 

                child.Arrange(rcChild); 
            } 

            return (arrangeSize); 
        }

        #endregion Protected Methods
 
        //-------------------------------------------------------------------
        // 
        //  Private Methods 
        //
        //------------------------------------------------------------------- 

        #region Private Methods

        internal static bool IsValidDock(object o) 
        {
            Dock dock = (Dock)o; 
 
            return (    dock == Dock.Left
                    ||  dock == Dock.Top 
                    ||  dock == Dock.Right
                    ||  dock == Dock.Bottom);
        }
 
        //
        //  This property 
        //  1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject 
        //  2. This is a performance optimization
        // 
        internal override int EffectiveValuesInitialSize
        {
            get { return 9; }
        } 

        #endregion Private Methods 
 
    }
} 


// 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