Border.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / Border.cs / 1 / Border.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// File: Border.cs 
//
// Description: Contains the Border Decorator class. 
//              Spec at [....]/layout/Specs/Border.xml 
//
// History: 
//  06/05/2003 : [....]  - Added to WCP branch (was BBPPresenter.cs in old branch)
//  07/19/2004 : [....]  - Update to allow for greater flexibility, etc.
//
//--------------------------------------------------------------------------- 

using MS.Internal; 
using MS.Internal.PresentationFramework; 
using MS.Utility;
using System; 
using System.Diagnostics;
using System.Windows.Threading;
using System.Windows.Media;
 
namespace System.Windows.Controls
{ 
 
    /// 
    /// The Border decorator is used to draw a border and/or background around another element. 
    /// 
    public class Border : Decorator
    {
        //------------------------------------------------------------------- 
        //
        //  Constructors 
        // 
        //-------------------------------------------------------------------
 
        #region Constructors

        /// 
        ///     Default DependencyObject constructor 
        /// 
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor 
        ///     that accepts a Dispatcher for best performance.
        ///  
        public Border() : base()
        {
        }
 
        #endregion
 
        //-------------------------------------------------------------------- 
        //
        //  Public Methods 
        //
        //-------------------------------------------------------------------

        //-------------------------------------------------------------------- 
        //
        //  Public Properties 
        // 
        //--------------------------------------------------------------------
 
        #region Public Properties

        /// 
        /// The BorderThickness property defined how thick a border to draw.  The property's value is a 
        ///  containing values for each of the Left, Top, Right,
        /// and Bottom sides.  Values of Auto are interpreted as zero. 
        ///  
        public Thickness BorderThickness
        { 
            get { return (Thickness) GetValue(BorderThicknessProperty); }
            set { SetValue(BorderThicknessProperty, value); }
        }
 
        /// 
        /// The Padding property inflates the effective size of the child by the specified thickness.  This 
        /// achieves the same effect as adding margin on the child, but is present here for convenience. 
        /// 
        public Thickness Padding 
        {
            get { return (Thickness) GetValue(PaddingProperty); }
            set { SetValue(PaddingProperty, value); }
        } 

        ///  
        /// The CornerRadius property allows users to control the roundness of the corners independently by 
        /// setting a radius value for each corner.  Radius values that are too large are scaled so that they
        /// smoothly blend from corner to corner. 
        /// 
        public CornerRadius CornerRadius
        {
            get { return (CornerRadius) GetValue(CornerRadiusProperty); } 
            set { SetValue(CornerRadiusProperty, value); }
 
        } 

        ///  
        /// The BorderBrush property defines the brush used to fill the border region.
        /// 
        public Brush BorderBrush
        { 
            get { return (Brush) GetValue(BorderBrushProperty); }
            set { SetValue(BorderBrushProperty, value); } 
        } 

        ///  
        /// The Background property defines the brush used to fill the area within the border.
        /// 
        public Brush Background
        { 
            get { return (Brush) GetValue(BackgroundProperty); }
            set { SetValue(BackgroundProperty, value); } 
        } 

        ///  
        /// DependencyProperty for  property.
        /// 
        [CommonDependencyProperty]
        public static readonly DependencyProperty BorderThicknessProperty 
            = DependencyProperty.Register("BorderThickness", typeof(Thickness), typeof(Border),
                                          new FrameworkPropertyMetadata( 
                                                new Thickness(), 
                                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
                                          new ValidateValueCallback(IsThicknessValid)); 

        private static bool IsThicknessValid(object value)
        {
            Thickness t = (Thickness)value; 
            return t.IsValid(false, false, false, false);
        } 
 
        /// 
        /// DependencyProperty for  property. 
        /// 
        public static readonly DependencyProperty PaddingProperty
            = DependencyProperty.Register("Padding", typeof(Thickness), typeof(Border),
                                          new FrameworkPropertyMetadata( 
                                                new Thickness(),
                                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), 
                                          new ValidateValueCallback(IsThicknessValid)); 

        ///  
        /// DependencyProperty for  property.
        /// 
        public static readonly DependencyProperty CornerRadiusProperty
            = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(Border), 
                                          new FrameworkPropertyMetadata(
                                                new CornerRadius(), 
                                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), 
                                          new ValidateValueCallback(IsCornerRadiusValid));
 
        private static bool IsCornerRadiusValid(object value)
        {
            CornerRadius cr = (CornerRadius)value;
            return (cr.IsValid(false, false, false, false)); 
        }
 
        ///  
        /// DependencyProperty for  property.
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty BorderBrushProperty
            = DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(Border),
                                          new FrameworkPropertyMetadata( 
                                                (Brush)null,
                                                FrameworkPropertyMetadataOptions.AffectsRender | 
                                                FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

        ///  
        /// DependencyProperty for  property.
        /// 
        [CommonDependencyProperty]
        public static readonly DependencyProperty BackgroundProperty = 
                Panel.BackgroundProperty.AddOwner(typeof(Border),
                        new FrameworkPropertyMetadata( 
                                (Brush)null, 
                                FrameworkPropertyMetadataOptions.AffectsRender |
                                FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender)); 

        #endregion Public Properties

        //------------------------------------------------------------------- 
        //
        //  Protected Methods 
        // 
        //--------------------------------------------------------------------
 
        #region Protected Methods

        /// 
        /// Updates DesiredSize of the Border.  Called by parent UIElement.  This is the first pass of layout. 
        /// 
        ///  
        /// Border determines its desired size it needs from the specified border the child: its sizing 
        /// properties, margin, and requested size.
        ///  
        /// Constraint size is an "upper limit" that the return value should not exceed.
        /// The Decorator's desired size.
        protected override Size MeasureOverride(Size constraint)
        { 
            UIElement child = Child;
            Size mySize = new Size(); 
 
            // Compute the chrome size added by the various elements
            Size border = HelperCollapseThickness(this.BorderThickness); 
            Size padding = HelperCollapseThickness(this.Padding);

            //If we have a child
            if (child != null) 
            {
                // Combine into total decorating size 
                Size combined = new Size(border.Width + padding.Width, border.Height + padding.Height); 

                // Remove size of border only from child's reference size. 
                Size childConstraint = new Size(Math.Max(0.0, constraint.Width - combined.Width),
                                                Math.Max(0.0, constraint.Height - combined.Height));

                child.Measure(childConstraint); 
                Size childSize = child.DesiredSize;
 
                // Now use the returned size to drive our size, by adding back the margins, etc. 
                mySize.Width = childSize.Width + combined.Width;
                mySize.Height = childSize.Height + combined.Height; 
            }
            else
            {
                // Combine into total decorating size 
                mySize = new Size(border.Width + padding.Width, border.Height + padding.Height);
            } 
 
            return mySize;
        } 


        /// 
        /// Border computes the position of its single child and applies its child's alignments to the child. 
        ///
        ///  
        /// The size reserved for this element by the parent 
        /// The actual ink area of the element, typically the same as finalSize
        protected override Size ArrangeOverride(Size finalSize) 
        {
            Thickness borders = BorderThickness;
            Rect boundRect = new Rect(finalSize);
            Rect innerRect = HelperDeflateRect(boundRect, borders); 

            //  arrange child 
            UIElement child = Child; 
            if (child != null)
            { 
                Rect childRect = HelperDeflateRect(innerRect, Padding);
                child.Arrange(childRect);
            }
 
            CornerRadius radii = CornerRadius;
            Brush borderBrush = BorderBrush; 
            bool uniformCorners = AreUniformCorners(radii); 

            //  decide which code path to execute. complex (geometry path based) rendering 
            //  is used if one of the following is true:

            //  1. there are non-uniform rounded corners
            _useComplexRenderCodePath = !uniformCorners; 

            if (    !_useComplexRenderCodePath 
                &&  borderBrush != null ) 
            {
                SolidColorBrush originIndependentBrush = borderBrush as SolidColorBrush; 

                bool uniformBorders = borders.IsUniform;

                _useComplexRenderCodePath = 
                //  2. the border brush is origin dependent (the only origin independent brush is a solid color brush)
                        (originIndependentBrush == null) 
                //  3. the border brush is semi-transtarent solid color brush AND border thickness is not uniform 
                //     (for uniform semi-transparent border Border.OnRender draws rectangle outline - so it works fine)
                    || ((originIndependentBrush.Color.A < 0xff) && !uniformBorders) 
                //  4. there are rounded corners AND the border thickness is not uniform
                    || (!DoubleUtil.IsZero(radii.TopLeft) && !uniformBorders);
            }
 
            if (_useComplexRenderCodePath)
            { 
                Radii innerRadii = new Radii(radii, borders, false); 

                //  calculate border / background rendering geometry 
                if (!DoubleUtil.IsZero(innerRect.Width) && !DoubleUtil.IsZero(innerRect.Height))
                {
                    _backgroundGeometry = new StreamGeometry();
 
                    using (StreamGeometryContext ctx = _backgroundGeometry.Open())
                    { 
                        GenerateGeometry(ctx, innerRect, innerRadii); 
                    }
 
                    _backgroundGeometry.Freeze();
                }
                else
                { 
                    _backgroundGeometry = null;
                } 
 
                if (!DoubleUtil.IsZero(boundRect.Width) && !DoubleUtil.IsZero(boundRect.Height))
                { 
                    Radii outerRadii = new Radii(radii, borders, true);
                    _borderGeometry = new StreamGeometry();

                    using (StreamGeometryContext ctx = _borderGeometry.Open()) 
                    {
                        GenerateGeometry(ctx, boundRect, outerRadii); 
 
                        if (_backgroundGeometry != null)
                        { 
                            GenerateGeometry(ctx, innerRect, innerRadii);
                        }
                    }
 
                    _borderGeometry.Freeze();
                } 
                else 
                {
                    _borderGeometry = null; 
                }
            }
            else
            { 
                _backgroundGeometry = null;
                _borderGeometry = null; 
            } 

            return (finalSize); 
        }

        /// 
        /// In addition to the child, Border renders a background + border.  The background is drawn inside the border. 
        /// 
        protected override void OnRender(DrawingContext dc) 
        { 
            if (_useComplexRenderCodePath)
            { 
                Brush brush;
                if (    _borderGeometry != null
                    &&  (brush = BorderBrush) != null   )
                { 
                    dc.DrawGeometry(brush, null, _borderGeometry);
                } 
 
                if (    _backgroundGeometry != null
                    &&  (brush = Background) != null    ) 
                {
                    dc.DrawGeometry(brush, null, _backgroundGeometry);
                }
            } 
            else
            { 
                Thickness border = BorderThickness; 
                Brush borderBrush;
 
                CornerRadius cornerRadius = CornerRadius;
                double outerCornerRadius = cornerRadius.TopLeft; // Already validated that all corners have the same radius
                bool roundedCorners = !DoubleUtil.IsZero(outerCornerRadius);
 
                // If we have a brush with which to draw the border, do so.
                // NB: We double draw corners right now.  Corner handling is tricky (bevelling, &c...) and 
                //     we need a firm spec before doing "the right thing."  ([....], ffortes) 
                if (!border.IsZero
                    && (borderBrush = BorderBrush) != null) 
                {
                    // Initialize the first pen.  Note that each pen is created via new()
                    // and frozen if possible.  Doing this avoids the pen
                    // being copied when used in the DrawLine methods. 
                    Pen pen = new Pen();
                    pen.Brush = borderBrush; 
                    pen.Thickness = border.Left; 
                    if (borderBrush.IsFrozen)
                    { 
                        pen.Freeze();
                    }

                    if (border.IsUniform) 
                    {
                        // Uniform border; stroke a rectangle. 
                        double halfThickness = pen.Thickness * 0.5; 

                        if (roundedCorners) 
                        {
                            dc.DrawRoundedRectangle(
                                null,
                                pen, 
                                new Rect(new Point(halfThickness, halfThickness),
                                new Point(RenderSize.Width - halfThickness, RenderSize.Height - halfThickness)), 
                                outerCornerRadius, 
                                outerCornerRadius);
                        } 
                        else
                        {
                            dc.DrawRectangle(
                                null, 
                                pen,
                                new Rect(new Point(halfThickness, halfThickness), 
                                new Point(RenderSize.Width - halfThickness, RenderSize.Height - halfThickness))); 
                        }
                    } 
                    else
                    {
                        // Nonuniform border; stroke each edge.
                        if (DoubleUtil.GreaterThan(border.Left, 0)) 
                        {
                            double halfThickness = pen.Thickness * 0.5; 
                            dc.DrawLine( 
                                pen,
                                new Point(halfThickness, 0), 
                                new Point(halfThickness, RenderSize.Height));
                        }

                        if (DoubleUtil.GreaterThan(border.Right, 0)) 
                        {
                            pen = new Pen(); 
                            pen.Brush = borderBrush; 
                            pen.Thickness = border.Right;
                            if (borderBrush.IsFrozen) 
                            {
                                pen.Freeze();
                            }
 
                            double halfThickness = pen.Thickness * 0.5;
                            dc.DrawLine( 
                                pen, 
                                new Point(RenderSize.Width - halfThickness, 0),
                                new Point(RenderSize.Width - halfThickness, RenderSize.Height)); 

                        }

                        if (DoubleUtil.GreaterThan(border.Top, 0)) 
                        {
                            pen = new Pen(); 
                            pen.Brush = borderBrush; 
                            pen.Thickness = border.Top;
                            if (borderBrush.IsFrozen) 
                            {
                                pen.Freeze();
                            }
 
                            double halfThickness = pen.Thickness * 0.5;
                            dc.DrawLine( 
                                pen, 
                                new Point(0, halfThickness),
                                new Point(RenderSize.Width, halfThickness)); 
                        }

                        if (DoubleUtil.GreaterThan(border.Bottom, 0))
                        { 
                            pen = new Pen();
                            pen.Brush = borderBrush; 
                            pen.Thickness = border.Bottom; 
                            if (borderBrush.IsFrozen)
                            { 
                                pen.Freeze();
                            }

                            double halfThickness = pen.Thickness * 0.5; 
                            dc.DrawLine(
                                pen, 
                                new Point(0, RenderSize.Height - halfThickness), 
                                new Point(RenderSize.Width, RenderSize.Height - halfThickness));
                        } 
                    }
                }

                // Draw background in rectangle inside border. 
                Brush background = Background;
                if (background != null) 
                { 
                    // Intialize background
                    Point ptTL = new Point(border.Left, border.Top); 
                    Point ptBR = new Point(RenderSize.Width - border.Right, RenderSize.Height - border.Bottom);

                    // Do not draw background if the borders are so large that they overlap.
                    if (ptBR.X > ptTL.X && ptBR.Y > ptTL.Y) 
                    {
                        if (roundedCorners) 
                        { 
                            Radii innerRadii = new Radii(cornerRadius, border, false); // Determine the inner edge radius
                            double innerCornerRadius = innerRadii.TopLeft;  // Already validated that all corners have the same radius 
                            dc.DrawRoundedRectangle(background, null, new Rect(ptTL, ptBR), innerCornerRadius, innerCornerRadius);
                        }
                        else
                        { 
                            dc.DrawRectangle(background, null, new Rect(ptTL, ptBR));
                        } 
                    } 
                }
            } 
        }

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

        #region Private Methods

        // Helper function to add up the left and right size as width, as well as the top and bottom size as height 
        private static Size HelperCollapseThickness(Thickness th)
        { 
            return new Size(th.Left + th.Right, th.Top + th.Bottom); 
        }
 
        private static bool AreUniformCorners(CornerRadius borderRadii)
        {
            double topLeft = borderRadii.TopLeft;
            return DoubleUtil.AreClose(topLeft, borderRadii.TopRight) && 
                DoubleUtil.AreClose(topLeft, borderRadii.BottomLeft) &&
                DoubleUtil.AreClose(topLeft, borderRadii.BottomRight); 
        } 

        /// Helper to deflate rectangle by thickness 
        private static Rect HelperDeflateRect(Rect rt, Thickness thick)
        {
            return new Rect(rt.Left + thick.Left,
                            rt.Top + thick.Top, 
                            Math.Max(0.0, rt.Width - thick.Left - thick.Right),
                            Math.Max(0.0, rt.Height - thick.Top - thick.Bottom)); 
        } 

        ///  
        ///     Generates a StreamGeometry.
        /// 
        /// An already opened StreamGeometryContext.
        /// Rectangle for geomentry conversion. 
        /// Corner radii.
        /// Result geometry. 
        private static void GenerateGeometry(StreamGeometryContext ctx, Rect rect, Radii radii) 
        {
            // 
            //  compute the coordinates of the key points
            //

            Point topLeft = new Point(radii.LeftTop, 0); 
            Point topRight = new Point(rect.Width - radii.RightTop, 0);
            Point rightTop = new Point(rect.Width, radii.TopRight); 
            Point rightBottom = new Point(rect.Width, rect.Height - radii.BottomRight); 
            Point bottomRight = new Point(rect.Width - radii.RightBottom, rect.Height);
            Point bottomLeft = new Point(radii.LeftBottom, rect.Height); 
            Point leftBottom = new Point(0, rect.Height - radii.BottomLeft);
            Point leftTop = new Point(0, radii.TopLeft);

            // 
            //  check keypoints for overlap and resolve by partitioning radii according to
            //  the percentage of each one. 
            // 

            //  top edge is handled here 
            if (topLeft.X > topRight.X)
            {
                double v = (radii.LeftTop) / (radii.LeftTop + radii.RightTop) * rect.Width;
                topLeft.X = v; 
                topRight.X = v;
            } 
 
            //  right edge
            if (rightTop.Y > rightBottom.Y) 
            {
                double v = (radii.TopRight) / (radii.TopRight + radii.BottomRight) * rect.Height;
                rightTop.Y = v;
                rightBottom.Y = v; 
            }
 
            //  bottom edge 
            if (bottomRight.X < bottomLeft.X)
            { 
                double v = (radii.LeftBottom) / (radii.LeftBottom + radii.RightBottom) * rect.Width;
                bottomRight.X = v;
                bottomLeft.X = v;
            } 

            // left edge 
            if (leftBottom.Y < leftTop.Y) 
            {
                double v = (radii.TopLeft) / (radii.TopLeft + radii.BottomLeft) * rect.Height; 
                leftBottom.Y = v;
                leftTop.Y = v;
            }
 
            //
            //  add on offsets 
            // 

            Vector offset = new Vector(rect.TopLeft.X, rect.TopLeft.Y); 
            topLeft += offset;
            topRight += offset;
            rightTop += offset;
            rightBottom += offset; 
            bottomRight += offset;
            bottomLeft += offset; 
            leftBottom += offset; 
            leftTop += offset;
 
            //
            //  create the border geometry
            //
            ctx.BeginFigure(topLeft, true /* is filled */, true /* is closed */); 

            // Top line 
            ctx.LineTo(topRight, true /* is stroked */, false /* is smooth join */); 

            // Upper-right corner 
            double radiusX = rect.TopRight.X - topRight.X;
            double radiusY = rightTop.Y - rect.TopRight.Y;
            if (!DoubleUtil.IsZero(radiusX)
                || !DoubleUtil.IsZero(radiusY)) 
            {
                ctx.ArcTo(rightTop, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); 
            } 

            // Right line 
            ctx.LineTo(rightBottom, true /* is stroked */, false /* is smooth join */);

            // Lower-right corner
            radiusX = rect.BottomRight.X - bottomRight.X; 
            radiusY = rect.BottomRight.Y - rightBottom.Y;
            if (!DoubleUtil.IsZero(radiusX) 
                || !DoubleUtil.IsZero(radiusY)) 
            {
                ctx.ArcTo(bottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); 
            }

            // Bottom line
            ctx.LineTo(bottomLeft, true /* is stroked */, false /* is smooth join */); 

            // Lower-left corner 
            radiusX = bottomLeft.X - rect.BottomLeft.X; 
            radiusY = rect.BottomLeft.Y - leftBottom.Y;
            if (!DoubleUtil.IsZero(radiusX) 
                || !DoubleUtil.IsZero(radiusY))
            {
                ctx.ArcTo(leftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
            } 

            // Left line 
            ctx.LineTo(leftTop, true /* is stroked */, false /* is smooth join */); 

            // Upper-left corner 
            radiusX = topLeft.X - rect.TopLeft.X;
            radiusY = leftTop.Y - rect.TopLeft.Y;
            if (!DoubleUtil.IsZero(radiusX)
                || !DoubleUtil.IsZero(radiusY)) 
            {
                ctx.ArcTo(topLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false); 
            } 
        }
 
        //
        //  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

        //------------------------------------------------------------------- 
        //
        //  Private Fields 
        // 
        //--------------------------------------------------------------------
 
        #region Private Fields
        private bool _useComplexRenderCodePath;
        private StreamGeometry _borderGeometry;
        private StreamGeometry _backgroundGeometry; 
        #endregion Private Fields
 
        //------------------------------------------------------------------- 
        //
        //  Private Structures Classes 
        //
        //--------------------------------------------------------------------

        #region Private Structures Classes 

        private struct Radii 
        { 
            internal Radii(CornerRadius radii, Thickness borders, bool outer)
            { 
                double left     = 0.5 * borders.Left;
                double top      = 0.5 * borders.Top;
                double right    = 0.5 * borders.Right;
                double bottom   = 0.5 * borders.Bottom; 

                if (outer) 
                { 
                    if (DoubleUtil.IsZero(radii.TopLeft))
                    { 
                        LeftTop = TopLeft = 0.0;
                    }
                    else
                    { 
                        LeftTop = radii.TopLeft + left;
                        TopLeft = radii.TopLeft + top; 
                    } 
                    if (DoubleUtil.IsZero(radii.TopRight))
                    { 
                        TopRight = RightTop = 0.0;
                    }
                    else
                    { 
                        TopRight = radii.TopRight + top;
                        RightTop = radii.TopRight + right; 
                    } 
                    if (DoubleUtil.IsZero(radii.BottomRight))
                    { 
                        RightBottom = BottomRight = 0.0;
                    }
                    else
                    { 
                        RightBottom = radii.BottomRight + right;
                        BottomRight = radii.BottomRight + bottom; 
                    } 
                    if (DoubleUtil.IsZero(radii.BottomLeft))
                    { 
                        BottomLeft = LeftBottom = 0.0;
                    }
                    else
                    { 
                        BottomLeft = radii.BottomLeft + bottom;
                        LeftBottom = radii.BottomLeft + left; 
                    } 
                }
                else 
                {
                    LeftTop     = Math.Max(0.0, radii.TopLeft - left);
                    TopLeft     = Math.Max(0.0, radii.TopLeft - top);
                    TopRight    = Math.Max(0.0, radii.TopRight - top); 
                    RightTop    = Math.Max(0.0, radii.TopRight - right);
                    RightBottom = Math.Max(0.0, radii.BottomRight - right); 
                    BottomRight = Math.Max(0.0, radii.BottomRight - bottom); 
                    BottomLeft  = Math.Max(0.0, radii.BottomLeft - bottom);
                    LeftBottom  = Math.Max(0.0, radii.BottomLeft - left); 
                }
            }

            internal double LeftTop; 
            internal double TopLeft;
            internal double TopRight; 
            internal double RightTop; 
            internal double RightBottom;
            internal double BottomRight; 
            internal double BottomLeft;
            internal double LeftBottom;
        }
 
        #endregion Private Structures Classes
    } 
} 

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