FreeFormPanel.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 / ndp / cdf / src / NetFx40 / Tools / System.Activities.Core.Presentation / System / Activities / Core / Presentation / FreeFormPanel.cs / 1305376 / FreeFormPanel.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Activities.Core.Presentation 
{
    using System.Activities.Presentation; 
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Windows; 
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media; 
    using System.Runtime;
    using System.Windows.Threading; 
    using System.Activities.Presentation.View; 

    internal sealed class FreeFormPanel : Panel 
    {
        public static readonly DependencyProperty ChildSizeProperty = DependencyProperty.RegisterAttached("ChildSize", typeof(Size), typeof(FreeFormPanel), new FrameworkPropertyMetadata());
        public static readonly Color ConnectorEditorColor = Colors.Gray;
        public static readonly DependencyProperty LocationProperty = DependencyProperty.RegisterAttached("Location", typeof(Point), typeof(FreeFormPanel), new FrameworkPropertyMetadata()); 
        public static readonly DependencyProperty RequiredWidthProperty = DependencyProperty.Register("RequiredWidth", typeof(Double), typeof(FreeFormPanel), new FrameworkPropertyMetadata(double.NaN));
        public static readonly DependencyProperty RequiredHeightProperty = DependencyProperty.Register("RequiredHeight", typeof(Double), typeof(FreeFormPanel), new FrameworkPropertyMetadata(double.NaN)); 
        public static readonly DependencyProperty DestinationConnectionPointProperty = DependencyProperty.RegisterAttached("DestinationConnectionPoint", typeof(ConnectionPoint), typeof(FreeFormPanel), new FrameworkPropertyMetadata()); 
        public static readonly DependencyProperty SourceConnectionPointProperty = DependencyProperty.RegisterAttached("SourceConnectionPoint", typeof(ConnectionPoint), typeof(FreeFormPanel), new FrameworkPropertyMetadata());
        public static readonly DependencyProperty DisabledProperty = DependencyProperty.Register("Disabled", typeof(bool), typeof(FreeFormPanel), new UIPropertyMetadata(false)); 

        public const double ConnectorEditorOpacity = 1.0;
        public const double ConnectorEditorThickness = 1.5;
        public const double LeftStackingMargin = 50; 
        public const double TopStackingMargin = 80;
        public const double VerticalStackingDistance = 50; 
        public ConnectorEditor connectorEditor; 
        double lastYPosition;
        static DesignerPerfEventProvider perfEventProvider = new DesignerPerfEventProvider(); 
        bool measureConnectors = false;
        bool measureConnectorsPosted = false;

        public FreeFormPanel() 
        {
            this.SnapsToDevicePixels = true; 
            this.AllowDrop = true; 
            connectorEditor = null;
            lastYPosition = FreeFormPanel.TopStackingMargin; 
        }

        public event LocationChangedEventHandler LocationChanged;
        public event ConnectorMovedEventHandler ConnectorMoved; 
        public event RequiredSizeChangedEventHandler RequiredSizeChanged;
 
        public static Size GetChildSize(DependencyObject obj) 
        {
            return (Size)obj.GetValue(FreeFormPanel.ChildSizeProperty); 
        }

        public double RequiredHeight
        { 
            get { return (double)GetValue(FreeFormPanel.RequiredHeightProperty); }
            private set { SetValue(FreeFormPanel.RequiredHeightProperty, value); } 
        } 

        public double RequiredWidth 
        {
            get { return (double)GetValue(FreeFormPanel.RequiredWidthProperty); }
            private set { SetValue(FreeFormPanel.RequiredWidthProperty, value); }
        } 

        public bool Disabled 
        { 
            get { return (bool)GetValue(DisabledProperty); }
            set { SetValue(DisabledProperty, value); } 
        }

        public static ConnectionPoint GetDestinationConnectionPoint(DependencyObject obj)
        { 
            return (ConnectionPoint)obj.GetValue(FreeFormPanel.DestinationConnectionPointProperty);
        } 
 
        public static ConnectionPoint GetSourceConnectionPoint(DependencyObject obj)
        { 
            return (ConnectionPoint)obj.GetValue(FreeFormPanel.SourceConnectionPointProperty);
        }

        public static void SetDestinationConnectionPoint(DependencyObject obj, ConnectionPoint connectionPoint) 
        {
            obj.SetValue(FreeFormPanel.DestinationConnectionPointProperty, connectionPoint); 
        } 

        public static void SetSourceConnectionPoint(DependencyObject obj, ConnectionPoint connectionPoint) 
        {
            obj.SetValue(FreeFormPanel.SourceConnectionPointProperty, connectionPoint);
        }
 

        public static Point GetLocation(DependencyObject obj) 
        { 
            return (Point)obj.GetValue(FreeFormPanel.LocationProperty);
        } 
        public static void SetChildSize(DependencyObject obj, Size size)
        {
            obj.SetValue(FreeFormPanel.ChildSizeProperty, size);
        } 

 
        public static void SetLocation(DependencyObject obj, Point point) 
        {
            obj.SetValue(FreeFormPanel.LocationProperty, point); 
        }

        public void UpdateConnectorPoints(Connector connector, List points)
        { 
            PointCollection pointCollection = new PointCollection();
            foreach (Point point in points) 
            { 
                pointCollection.Add(new Point(point.X < 0 ? 0 : point.X, point.Y < 0 ? 0 : point.Y));
            } 
            connector.Points = pointCollection;
            OnLocationChanged(connector, null);
        }
 
        protected override Size ArrangeOverride(Size finalSize)
        { 
            double height = 0; 
            double width = 0;
            for (int i = 0; i < Children.Count; i++) 
            {
                Point pt = new Point(0, 0);
                Size size = Children[i].DesiredSize;
                if (Children[i].GetType() == typeof(Connector)) 
                {
                    ((UIElement)Children[i]).Arrange(new Rect(pt, size)); 
                } 
                else
                { 
                    pt = FreeFormPanel.GetLocation(Children[i]);
                    ((UIElement)Children[i]).Arrange(new Rect(pt, size));
                }
                if (width < (size.Width + pt.X)) 
                {
                    width = size.Width + pt.X; 
                } 
                if (height < (size.Height + pt.Y))
                { 
                    height = size.Height + pt.Y;
                }
            }
            width = (width < this.MinWidth) ? this.MinWidth : width; 
            width = (width < this.Width) ? (this.Width < Double.MaxValue ? this.Width : width) : width;
 
            height = (height < this.MinHeight) ? this.MinHeight : height; 
            height = (height < this.Height) ? (this.Height < Double.MaxValue ? this.Height : height) : height;
 
            return new Size(width, height);
        }

        protected override Size MeasureOverride(Size availableSize) 
        {
            perfEventProvider.FreeFormPanelMeasureStart(); 
            base.MeasureOverride(availableSize); 
            double height = 0, width = 0;
            Point pt = new Point(0, 0); 
            foreach (UIElement child in Children)
            {
                Connector connectorChild = child as Connector;
                if (connectorChild != null) 
                {
                    pt = new Point(0, 0); 
                    if (measureConnectors) 
                    {
                        if (connectorChild.Points.Count == 0 || 
                            !this.Disabled &&
                            ((DesignerGeometryHelper.DistanceBetweenPoints(connectorChild.Points[0], FreeFormPanel.GetSourceConnectionPoint(connectorChild).Location) > 1)
                            || (DesignerGeometryHelper.DistanceBetweenPoints(connectorChild.Points[connectorChild.Points.Count - 1], FreeFormPanel.GetDestinationConnectionPoint(connectorChild).Location) > 1)))
                        { 
                            connectorChild.Points = new PointCollection();
                            RoutePolyLine(connectorChild); 
                        } 
                        connectorChild.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
                    } 
                    else
                    {
                        continue;
                    } 
                }
                else //Measure non-connector elements. 
                { 
                    child.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
                    if (!child.DesiredSize.Equals(((Size)FreeFormPanel.GetChildSize(child)))) 
                    {
                        FreeFormPanel.SetChildSize(child, child.DesiredSize);
                    }
                    pt = FreeFormPanel.GetLocation(child); 
                    if (pt.X == 0 && pt.Y == 0)
                    { 
                        pt = new Point(LeftStackingMargin, lastYPosition); 
                        OnLocationChanged(child, new LocationChangedEventArgs(pt));
                        FreeFormPanel.SetLocation(child, pt); 
                        lastYPosition += child.DesiredSize.Height + VerticalStackingDistance;
                    }
                }
                if (height < child.DesiredSize.Height + pt.Y) 
                {
                    height = child.DesiredSize.Height + pt.Y; 
                } 
                if (width < child.DesiredSize.Width + pt.X)
                { 
                    width = child.DesiredSize.Width + pt.X;
                }
            }
            //Returned width will be the largest out of 
            //1. calculated width, 2. this.MinWidth, 3. this.Width.
            //We set the RequiredWidth so that the container doesn't clip the panel. 
            width = (width < this.MinWidth) ? this.MinWidth : width; 
            double oldRequiredWidth = this.RequiredWidth;
            double newRequiredWidth = width; 
            width = (width < this.Width) ? (this.Width < Double.MaxValue ? this.Width : width) : width;
            height = (height < this.MinHeight) ? this.MinHeight : height;
            double oldRequiredHeight = this.RequiredHeight;
            double newRequiredHeight = height; 
            if (this.RequiredSizeChanged != null)
            { 
                this.RequiredSizeChanged(this, new RequiredSizeChangedEventArgs(new Size(oldRequiredWidth, oldRequiredHeight), new Size(newRequiredWidth, newRequiredHeight))); 
            }
            this.RequiredWidth = newRequiredWidth; 
            this.RequiredHeight = newRequiredHeight;
            height = (height < this.Height) ? (this.Height < Double.MaxValue ? this.Height : height) : height;
            Action MeasureConnectors = () =>
            { 
                //This action will execute at Input priority.
                //Enabling the measure on Connectors and forcing a MeasureOverride by calling InvalidateMeasure. 
                this.measureConnectors = true; 
                this.InvalidateMeasure();
            }; 
            if (!measureConnectorsPosted)
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Input, MeasureConnectors);
                measureConnectorsPosted = true; 
            }
            if (measureConnectors) 
            { 
                measureConnectors = false;
                measureConnectorsPosted = false; 
            }
            perfEventProvider.FreeFormPanelMeasureEnd();
            return new Size(width, height);
        } 

 
        void OnLocationChanged(Object sender, LocationChangedEventArgs e) 
        {
            if (LocationChanged != null) 
            {
                LocationChanged(sender, e);
            }
        } 

        protected override void OnMouseLeave(MouseEventArgs e) 
        { 
            if (!this.Disabled)
            { 
                if (connectorEditor != null && connectorEditor.BeingEdited
                    && !(Mouse.DirectlyOver is ConnectionPointsAdorner))
                {
                    SaveConnectorEditor(e.GetPosition(this)); 
                }
            } 
            base.OnMouseLeave(e); 
        }
 

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (!this.Disabled) 
            {
                if (e.LeftButton == MouseButtonState.Pressed) 
                { 
                    if (connectorEditor != null && connectorEditor.BeingEdited)
                    { 
                        AutoScrollHelper.AutoScroll(e, this);
                        connectorEditor.Update(e.GetPosition(this));
                        e.Handled = true;
                    } 
                }
            } 
            base.OnMouseMove(e); 
        }
 
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            if (!this.Disabled)
            { 
                if (connectorEditor != null && connectorEditor.BeingEdited)
                { 
                    SaveConnectorEditor(e.GetPosition(this)); 
                }
            } 
            base.OnMouseLeftButtonUp(e);
        }

        public void RemoveConnectorEditor() 
        {
            if (connectorEditor != null) 
            { 
                connectorEditor.Remove();
                connectorEditor = null; 
            }

        }
 
        protected override void OnKeyDown(KeyEventArgs e)
        { 
            if (!this.Disabled) 
            {
                if (e.Key == Key.Escape) 
                {
                    //If escape key is hit while dragging a connector, end the dragging.
                    if (connectorEditor != null && connectorEditor.BeingEdited)
                    { 
                        Connector affectedConnector = connectorEditor.Connector;
                        RemoveConnectorEditor(); 
                        this.connectorEditor = new ConnectorEditor(this, affectedConnector); 
                        e.Handled = true;
                    } 
                }
            }
            base.OnKeyDown(e);
        } 

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) 
        { 
            if (!this.Disabled)
            { 
                //If one of the edit points is clicked, update the connector editor.
                if ((connectorEditor != null) && connectorEditor.EditPointsHitTest(e.GetPosition(this)))
                {
                    connectorEditor.Update(e.GetPosition(this)); 
                    e.Handled = true;
                } 
                else 
                {
                    CreateNewConnectorEditor(e); 
                }
            }
            base.OnPreviewMouseLeftButtonDown(e);
        } 

        protected override void OnPreviewMouseRightButtonDown(MouseButtonEventArgs e) 
        { 
            if (!this.Disabled)
            { 
                CreateNewConnectorEditor(e);
            }
            base.OnPreviewMouseRightButtonDown(e);
        } 

        void CreateNewConnectorEditor(MouseButtonEventArgs e) 
        { 
            if (connectorEditor == null || !e.Source.Equals(connectorEditor.Connector))
            { 
                //If user clicks anywhere other than the connector editor, destroy it.
                RemoveConnectorEditor();
                if (e.Source.GetType().IsAssignableFrom(typeof(Connector)))
                { 
                    this.connectorEditor = new ConnectorEditor(this, e.Source as Connector);
                } 
            } 
        }
 
        //Calls the Line routing algorithm and populates the points collection of the connector.
        void RoutePolyLine(Connector connector)
        {
            Point[] pts = ConnectorRouter.Route(this, FreeFormPanel.GetSourceConnectionPoint(connector), FreeFormPanel.GetDestinationConnectionPoint(connector)); 
            List points = new List(pts);
            if (pts != null) 
            { 
                UpdateConnectorPoints(connector, points);
            } 
        }


        //Connector editing is complete, save the final connectorEditor state into the connector. 
        void SaveConnectorEditor(Point pt)
        { 
            //Point snappedPoint = SnapPointToGrid(pt); 
            if (!connectorEditor.Persist(pt))
            { 
                //Persist will return false, when the ConnectionEndPoint has been moved.
                if (this.ConnectorMoved != null)
                {
                    // Must remove the ConnectorEditor before calling ConnectorMoved 
                    // The reason is ConnectorMoved may show error message box and waiting for response
                    // while other mouse event could be handled in the this moment(ConnectorEditor could 
                    // still be accessed by the handler if it is not removed. 
                    Connector connector = this.connectorEditor.Connector;
                    List points = this.connectorEditor.ConnectorEditorLocation; 
                    RemoveConnectorEditor();

                    ConnectorMoved(connector, new ConnectorMovedEventArgs(points));
                } 
                else
                { 
                    RemoveConnectorEditor(); 
                }
            } 
            else
            {
                this.InvalidateMeasure();
            } 

        } 
 

    } 


}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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