ExtensionWindow.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / View / ExtensionWindow.cs / 1305376 / ExtensionWindow.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.View
{ 
    using System.Collections.ObjectModel;
    using System.Collections.Specialized; 
    using System.ComponentModel; 
    using System.Windows;
    using System.Windows.Controls; 
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Runtime; 
    using System.Globalization;
    using System.Diagnostics.CodeAnalysis; 
 
    delegate void ExtensionWindowCloseEventHandler(object sender, RoutedEventArgs e);
    delegate void ExtensionWindowClosingEventHandler(object sender, ExtensionWindowClosingRoutedEventArgs e); 

    //This class provides PopupWindow like expirience while editing data on designer surface. It
    //behaves like ordinary popup, with additional functionality - allows resizing, moving, and
    //easier styling. 
    [TemplatePart(Name = "PART_Content"),
     TemplatePart(Name = "PART_ShapeBorder")] 
    class ExtensionWindow : ContentControl 
    {
 
        public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
                "Data",
                typeof(object),
                typeof(ExtensionWindow), 
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnDataChanged)));
 
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( 
                "Title",
                typeof(string), 
                typeof(ExtensionWindow),
                new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty IconProperty = DependencyProperty.Register( 
                "Icon",
                typeof(DrawingBrush), 
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(null));
 
        public static readonly DependencyProperty ShowWindowHeaderProperty = DependencyProperty.Register(
                "ShowWindowHeader",
                typeof(bool),
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(true));
 
        public static readonly DependencyProperty ShowResizeGripProperty = DependencyProperty.Register( 
                "ShowResizeGrip",
                typeof(bool), 
                typeof(ExtensionWindow),
                new UIPropertyMetadata(true));

        public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register( 
                "MenuItems",
                typeof(ObservableCollection), 
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(new ObservableCollection()));
 
        public static readonly DependencyProperty IsResizableProperty = DependencyProperty.Register(
                "IsResizable",
                typeof(bool),
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(false));
 
 
        public static readonly RoutedEvent ClosingEvent = EventManager.RegisterRoutedEvent("Closing",
                RoutingStrategy.Bubble, 
                typeof(ExtensionWindowClosingEventHandler),
                typeof(ExtensionWindow));

        public static readonly RoutedEvent CloseEvent = EventManager.RegisterRoutedEvent("Close", 
                RoutingStrategy.Bubble,
                typeof(ExtensionWindowCloseEventHandler), 
                typeof(ExtensionWindow)); 

        public static readonly RoutedEvent VisibilityChangedEvent = EventManager.RegisterRoutedEvent("VisibilityChanged", 
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(ExtensionWindow));
 
        static readonly double BorderOffset = 20.0;
 
        ContentPresenter presenter; 
        ExtensionSurface surface;
        Border border; 
        ResizeValues resizeOption = ResizeValues.NONE;
        Point bottomRight;

        [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.InitializeReferenceTypeStaticFieldsInline, 
            Justification = "Overriding metadata for dependency properties in static constructor is the way suggested by WPF")]
        static ExtensionWindow() 
        { 
            VisibilityProperty.AddOwner(typeof(ExtensionWindow), new PropertyMetadata(OnVisibilityChanged));
 
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(ExtensionWindow),
                new FrameworkPropertyMetadata(typeof(ExtensionWindow)));
        } 

        protected override void OnInitialized(EventArgs e) 
        { 
            base.OnInitialized(e);
            this.MenuItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnMenuItemsChanged); 
            this.DataContext = this;

        }
 
        public event ExtensionWindowClosingEventHandler Closing
        { 
            add 
            {
                AddHandler(ClosingEvent, value); 
            }
            remove
            {
                RemoveHandler(ClosingEvent, value); 
            }
        } 
 

        public event ExtensionWindowCloseEventHandler Close 
        {
            add
            {
                AddHandler(CloseEvent, value); 
            }
            remove 
            { 
                RemoveHandler(CloseEvent, value);
            } 
        }

        public event RoutedEventHandler VisibilityChanged
        { 
            add
            { 
                AddHandler(VisibilityChangedEvent, value); 
            }
            remove 
            {
                RemoveHandler(VisibilityChangedEvent, value);
            }
        } 

 
        public object Data 
        {
            get { return (object)GetValue(DataProperty); } 
            set { SetValue(DataProperty, value); }
        }

        public string Title 
        {
            get { return (string)GetValue(TitleProperty); } 
            set { SetValue(TitleProperty, value); } 
        }
 
        [Fx.Tag.KnownXamlExternal]
        public DrawingBrush Icon
        {
            get { return (DrawingBrush)GetValue(IconProperty); } 
            set { SetValue(IconProperty, value); }
        } 
 
        public bool ShowWindowHeader
        { 
            get { return (bool)GetValue(ShowWindowHeaderProperty); }
            set { SetValue(ShowWindowHeaderProperty, value); }
        }
 
        public bool ShowResizeGrip
        { 
            get { return (bool)GetValue(ShowResizeGripProperty); } 
            set { SetValue(ShowResizeGripProperty, value); }
        } 

        [Fx.Tag.KnownXamlExternal]
        public ObservableCollection MenuItems
        { 
            get { return (ObservableCollection)GetValue(MenuItemsProperty); }
        } 
 
        public ExtensionSurface Surface
        { 
            get { return this.surface; }
        }

        public bool IsResizable 
        {
            get { return (bool)GetValue(IsResizableProperty); } 
            set { SetValue(IsResizableProperty, value); } 
        }
 
        protected ContentPresenter ContentPresenter
        {
            get { return this.presenter; }
        } 

        public Point GetPlacementTargetOffset() 
        { 
            Point offset = new Point();
            FrameworkElement target = ExtensionSurface.GetPlacementTarget(this); 
            if (null != target)
            {
                FrameworkElement commonRoot = target.FindCommonVisualAncestor(this) as FrameworkElement;
                MatrixTransform transform = (MatrixTransform)target.TransformToAncestor(commonRoot); 
                Point targetPosition = transform.Transform(new Point());
                Point windowPosition = ExtensionSurface.GetPosition(this); 
                offset.X = targetPosition.X - windowPosition.X; 
                offset.Y = targetPosition.Y - windowPosition.Y;
            } 
            return offset;
        }

 
        static void OnDataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            ((ExtensionWindow)sender).OnDataChanged(args.OldValue, args.NewValue); 
        }
 
        static void OnPositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((ExtensionWindow)sender).OnPositionChanged((Point)args.NewValue);
        } 

        static void OnVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        { 
            ((ExtensionWindow)sender).OnVisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
        } 

        protected override void OnVisualParentChanged(DependencyObject oldParent)
        {
            base.OnVisualParentChanged(oldParent); 
            ExtensionWindow dummy;
            if (!DesignerProperties.GetIsInDesignMode(this) && !TryGetParentExtensionWindow(this, out dummy, out this.surface)) 
            { 
                Fx.Assert(string.Format(CultureInfo.InvariantCulture, "ExtensionWindow '{0}' cannot be used outside ExtensionSurface", this.Name));
            } 
        }

        protected virtual void OnDataChanged(object oldData, object newData)
        { 
        }
 
        protected virtual void OnVisibilityChanged(Visibility oldValue, Visibility newValue) 
        {
            RaiseEvent(new RoutedEventArgs(VisibilityChangedEvent, this)); 
        }

        protected virtual void OnPositionChanged(Point position)
        { 
            if (null != this.surface)
            { 
                this.surface.SetWindowPosition(this, position); 
            }
        } 

        public bool TryFindElement(string elementName, out object element)
        {
            //helper method - it looks for named visual elements in the template provided by the user 
            element = null;
            if (null != this.presenter) 
            { 
                element = this.presenter.ContentTemplate.FindName(elementName, this.presenter);
            } 
            return (null != element);
        }

        public override void OnApplyTemplate() 
        {
            base.OnApplyTemplate(); 
            //lookup for content presenter (should always be there) 
            this.presenter = this.Template.FindName("PART_Content", this) as ContentPresenter;
            if (!DesignerProperties.GetIsInDesignMode(this) && null != this.presenter && null == this.presenter.Content) 
            {
                //setup bindings - datacontext and content may possibly change, so i want them beeing set via databinding
                Binding binding = new Binding();
                binding.Source = this; 
                this.presenter.SetBinding(ContentPresenter.ContentProperty, binding);
                binding = new Binding(); 
                binding.Source = this; 
                this.presenter.SetBinding(ContentPresenter.DataContextProperty, binding);
                this.presenter.ApplyTemplate(); 
            }
            this.border = this.Template.FindName("PART_ShapeBorder", this) as Border;
            if (null != this.border)
            { 
                this.border.MouseMove += OnBorderMouseMove;
                this.border.MouseDown += OnBorderMouseDown; 
                this.border.MouseUp += OnBorderMouseUp; 
                this.border.MouseLeave += OnBorderMouseLeave;
            } 
        }

        static internal void RaiseWindowCloseEvent(ExtensionWindow sender)
        { 
            ExtensionWindowClosingRoutedEventArgs args = new ExtensionWindowClosingRoutedEventArgs(ClosingEvent, sender);
            sender.RaiseEvent(args); 
            if (!args.Cancel) 
            {
                sender.RaiseEvent(new RoutedEventArgs(CloseEvent, sender)); 
            }
        }

        void OnBorderMouseMove(object sender, MouseEventArgs e) 
        {
            if (!this.border.IsMouseCaptured) 
            { 
                if (this.border.IsMouseDirectlyOver && this.IsResizable && ExtensionSurface.GetMode(this) == ExtensionSurface.PlacementMode.Absolute)
                { 
                    Point position = e.GetPosition(this.border);

                    if (position.X <= BorderOffset && position.Y <= BorderOffset)
                    { 
                        this.resizeOption = ResizeValues.TopLeft;
                        Mouse.OverrideCursor = Cursors.SizeNWSE; 
                    } 
                    else if (position.X >= this.border.ActualWidth - BorderOffset && position.Y <= BorderOffset)
                    { 
                        this.resizeOption = ResizeValues.TopRight;
                        Mouse.OverrideCursor = Cursors.SizeNESW;
                    }
                    else if (position.X <= BorderOffset && position.Y >= this.border.ActualHeight - BorderOffset) 
                    {
                        this.resizeOption = ResizeValues.BottomLeft; 
                        Mouse.OverrideCursor = Cursors.SizeNESW; 
                    }
                    else if (position.X >= this.border.ActualWidth - BorderOffset && position.Y >= this.border.ActualHeight - BorderOffset) 
                    {
                        this.resizeOption = ResizeValues.BottomRight;
                        Mouse.OverrideCursor = Cursors.SizeNWSE;
                    } 
                    else if (position.Y <= (BorderOffset / 2.0))
                    { 
                        this.resizeOption = ResizeValues.Top; 
                        Mouse.OverrideCursor = Cursors.SizeNS;
                    } 
                    else if (position.Y >= this.border.ActualHeight - (BorderOffset / 2.0))
                    {
                        this.resizeOption = ResizeValues.Bottom;
                        Mouse.OverrideCursor = Cursors.SizeNS; 
                    }
                    else if (position.X <= (BorderOffset / 2.0)) 
                    { 
                        this.resizeOption = ResizeValues.Left;
                        Mouse.OverrideCursor = Cursors.SizeWE; 
                    }
                    else if (position.X >= this.border.ActualWidth - (BorderOffset / 2.0))
                    {
                        this.resizeOption = ResizeValues.Right; 
                        Mouse.OverrideCursor = Cursors.SizeWE;
                    } 
                    else 
                    {
                        Mouse.OverrideCursor = null; 
                        this.resizeOption = ResizeValues.NONE;
                    }
                    Point topLeft = ExtensionSurface.GetPosition(this);
                    this.bottomRight = new Point(topLeft.X + Width, topLeft.Y + Height); 
                }
                else if (Mouse.OverrideCursor != null) 
                { 
                    Mouse.OverrideCursor = null;
                    this.resizeOption = ResizeValues.NONE; 
                }
            }
            else if (e.LeftButton == MouseButtonState.Pressed)
            { 
                this.HandleWindowResize();
            } 
        } 

        void OnBorderMouseDown(object sender, MouseButtonEventArgs e) 
        {
            if (this.resizeOption != ResizeValues.NONE && sender == this.border)
            {
                Mouse.Capture(this.border); 
            }
        } 
 
        void OnBorderMouseUp(object sender, MouseButtonEventArgs e)
        { 
            if (this.border.IsMouseCaptured)
            {
                Mouse.Capture(null);
            } 
        }
 
        void OnBorderMouseLeave(object sender, MouseEventArgs e) 
        {
            this.resizeOption = ResizeValues.NONE; 
            Mouse.OverrideCursor = null;
        }

        void HandleWindowResize() 
        {
            switch (this.resizeOption) 
            { 
                case ResizeValues.Top:
                    CalculateSize(false, true, false, true); 
                    break;

                case ResizeValues.TopLeft:
                    CalculateSize(true, true, true, true); 
                    break;
 
                case ResizeValues.Left: 
                    CalculateSize(true, false, true, false);
                    break; 

                case ResizeValues.BottomLeft:
                    CalculateSize(true, false, true, true);
                    break; 

                case ResizeValues.TopRight: 
                    CalculateSize(false, true, true, true); 
                    break;
 
                case ResizeValues.Bottom:
                    CalculateSize(false, false, false, true);
                    break;
 
                case ResizeValues.Right:
                    CalculateSize(false, false, true, false); 
                    break; 

                case ResizeValues.BottomRight: 
                    CalculateSize(false, false, true, true);
                    break;

                default: 
                    Fx.Assert("not supported resize option " + this.resizeOption);
                    break; 
            }; 
        }
 
        void CalculateSize(bool changeX, bool changeY, bool changeWidth, bool changeHeight)
        {
            Point current = Mouse.GetPosition(this);
            Point absolutePosition = Mouse.GetPosition(this.surface); 

            Point topLeft = ExtensionSurface.GetPosition(this); 
 
            double initialHeight = this.bottomRight.Y - topLeft.Y;
            double initialWidth = this.bottomRight.X - topLeft.X; 

            Size size = new Size(initialWidth, initialHeight);

            if (changeX) 
            {
                if (bottomRight.X > absolutePosition.X) 
                { 
                    if ((double.IsNaN(MinWidth) || double.IsInfinity(MinWidth) || bottomRight.X - absolutePosition.X >= MinWidth) &&
                        (double.IsNaN(MaxWidth) || double.IsInfinity(MaxWidth) || bottomRight.X - absolutePosition.X <= MaxWidth)) 
                    {
                        size.Width = this.bottomRight.X - absolutePosition.X;
                        topLeft.X = absolutePosition.X;
                    } 
                }
            } 
            else 
            {
                if (changeWidth) 
                {
                    size.Width = Math.Min(Math.Max(MinWidth, current.X), MaxWidth);
                }
            } 
            if (changeY)
            { 
                if (bottomRight.Y > absolutePosition.Y) 
                {
                    if ((double.IsNaN(MinHeight) || double.IsInfinity(MinHeight) || bottomRight.Y - absolutePosition.Y >= MinHeight) && 
                        (double.IsNaN(MaxHeight) || double.IsInfinity(MaxHeight) || bottomRight.Y - absolutePosition.Y <= MaxHeight))
                    {
                        size.Height = this.bottomRight.Y - absolutePosition.Y;
                        topLeft.Y = absolutePosition.Y; 
                    }
                } 
            } 
            else
            { 
                if (changeHeight)
                {
                    size.Height = Math.Min(Math.Max(MinHeight, current.Y), MaxHeight);
                } 
            }
            if (changeX || changeY) 
            { 
                this.surface.SetWindowPosition(this, topLeft);
            } 
            this.surface.SetSize(this, size);
        }

        protected override void OnKeyDown(KeyEventArgs e) 
        {
            //if ESC - close me 
            if (e.Key == Key.Escape) 
            {
                RaiseWindowCloseEvent(this); 
            }
            base.OnKeyDown(e);
        }
 
        protected override void OnMouseDown(MouseButtonEventArgs e)
        { 
            base.OnMouseDown(e); 
            this.SelectWindow();
        } 



        public void SelectWindow() 
        {
            this.surface.SelectWindow(this); 
        } 

        void OnMenuItemsChanged(object sender, NotifyCollectionChangedEventArgs e) 
        {
            if (null != e.NewItems)
            {
                foreach (MenuItem item in e.NewItems) 
                {
                    item.DataContext = this; 
                } 
            }
        } 


        internal static bool TryGetParentExtensionWindow(FrameworkElement element, out ExtensionWindow window, out ExtensionSurface surface)
        { 
            window = null;
            surface = null; 
            if (null != element) 
            {
                FrameworkElement current = element; 
                window = element.TemplatedParent as ExtensionWindow;
                while (null == window && null != current)
                {
                    window = current as ExtensionWindow; 
                    current = (FrameworkElement)current.Parent;
                } 
                if (null != window) 
                {
                    current = window; 
                    surface = window.TemplatedParent as ExtensionSurface;
                    while (null == surface && null != current)
                    {
                        surface = current as ExtensionSurface; 
                        current = (FrameworkElement)current.Parent;
                    } 
                } 
            }
            return (null != window && null != surface); 
        }

        enum ResizeValues
        { 
            NONE,
            TopLeft, 
            Left, 
            BottomLeft,
            Bottom, 
            BottomRight,
            Right,
            TopRight,
            Top, 
        };
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.View
{ 
    using System.Collections.ObjectModel;
    using System.Collections.Specialized; 
    using System.ComponentModel; 
    using System.Windows;
    using System.Windows.Controls; 
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Runtime; 
    using System.Globalization;
    using System.Diagnostics.CodeAnalysis; 
 
    delegate void ExtensionWindowCloseEventHandler(object sender, RoutedEventArgs e);
    delegate void ExtensionWindowClosingEventHandler(object sender, ExtensionWindowClosingRoutedEventArgs e); 

    //This class provides PopupWindow like expirience while editing data on designer surface. It
    //behaves like ordinary popup, with additional functionality - allows resizing, moving, and
    //easier styling. 
    [TemplatePart(Name = "PART_Content"),
     TemplatePart(Name = "PART_ShapeBorder")] 
    class ExtensionWindow : ContentControl 
    {
 
        public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
                "Data",
                typeof(object),
                typeof(ExtensionWindow), 
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnDataChanged)));
 
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( 
                "Title",
                typeof(string), 
                typeof(ExtensionWindow),
                new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty IconProperty = DependencyProperty.Register( 
                "Icon",
                typeof(DrawingBrush), 
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(null));
 
        public static readonly DependencyProperty ShowWindowHeaderProperty = DependencyProperty.Register(
                "ShowWindowHeader",
                typeof(bool),
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(true));
 
        public static readonly DependencyProperty ShowResizeGripProperty = DependencyProperty.Register( 
                "ShowResizeGrip",
                typeof(bool), 
                typeof(ExtensionWindow),
                new UIPropertyMetadata(true));

        public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register( 
                "MenuItems",
                typeof(ObservableCollection), 
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(new ObservableCollection()));
 
        public static readonly DependencyProperty IsResizableProperty = DependencyProperty.Register(
                "IsResizable",
                typeof(bool),
                typeof(ExtensionWindow), 
                new UIPropertyMetadata(false));
 
 
        public static readonly RoutedEvent ClosingEvent = EventManager.RegisterRoutedEvent("Closing",
                RoutingStrategy.Bubble, 
                typeof(ExtensionWindowClosingEventHandler),
                typeof(ExtensionWindow));

        public static readonly RoutedEvent CloseEvent = EventManager.RegisterRoutedEvent("Close", 
                RoutingStrategy.Bubble,
                typeof(ExtensionWindowCloseEventHandler), 
                typeof(ExtensionWindow)); 

        public static readonly RoutedEvent VisibilityChangedEvent = EventManager.RegisterRoutedEvent("VisibilityChanged", 
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(ExtensionWindow));
 
        static readonly double BorderOffset = 20.0;
 
        ContentPresenter presenter; 
        ExtensionSurface surface;
        Border border; 
        ResizeValues resizeOption = ResizeValues.NONE;
        Point bottomRight;

        [SuppressMessage(FxCop.Category.Performance, FxCop.Rule.InitializeReferenceTypeStaticFieldsInline, 
            Justification = "Overriding metadata for dependency properties in static constructor is the way suggested by WPF")]
        static ExtensionWindow() 
        { 
            VisibilityProperty.AddOwner(typeof(ExtensionWindow), new PropertyMetadata(OnVisibilityChanged));
 
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(ExtensionWindow),
                new FrameworkPropertyMetadata(typeof(ExtensionWindow)));
        } 

        protected override void OnInitialized(EventArgs e) 
        { 
            base.OnInitialized(e);
            this.MenuItems.CollectionChanged += new NotifyCollectionChangedEventHandler(OnMenuItemsChanged); 
            this.DataContext = this;

        }
 
        public event ExtensionWindowClosingEventHandler Closing
        { 
            add 
            {
                AddHandler(ClosingEvent, value); 
            }
            remove
            {
                RemoveHandler(ClosingEvent, value); 
            }
        } 
 

        public event ExtensionWindowCloseEventHandler Close 
        {
            add
            {
                AddHandler(CloseEvent, value); 
            }
            remove 
            { 
                RemoveHandler(CloseEvent, value);
            } 
        }

        public event RoutedEventHandler VisibilityChanged
        { 
            add
            { 
                AddHandler(VisibilityChangedEvent, value); 
            }
            remove 
            {
                RemoveHandler(VisibilityChangedEvent, value);
            }
        } 

 
        public object Data 
        {
            get { return (object)GetValue(DataProperty); } 
            set { SetValue(DataProperty, value); }
        }

        public string Title 
        {
            get { return (string)GetValue(TitleProperty); } 
            set { SetValue(TitleProperty, value); } 
        }
 
        [Fx.Tag.KnownXamlExternal]
        public DrawingBrush Icon
        {
            get { return (DrawingBrush)GetValue(IconProperty); } 
            set { SetValue(IconProperty, value); }
        } 
 
        public bool ShowWindowHeader
        { 
            get { return (bool)GetValue(ShowWindowHeaderProperty); }
            set { SetValue(ShowWindowHeaderProperty, value); }
        }
 
        public bool ShowResizeGrip
        { 
            get { return (bool)GetValue(ShowResizeGripProperty); } 
            set { SetValue(ShowResizeGripProperty, value); }
        } 

        [Fx.Tag.KnownXamlExternal]
        public ObservableCollection MenuItems
        { 
            get { return (ObservableCollection)GetValue(MenuItemsProperty); }
        } 
 
        public ExtensionSurface Surface
        { 
            get { return this.surface; }
        }

        public bool IsResizable 
        {
            get { return (bool)GetValue(IsResizableProperty); } 
            set { SetValue(IsResizableProperty, value); } 
        }
 
        protected ContentPresenter ContentPresenter
        {
            get { return this.presenter; }
        } 

        public Point GetPlacementTargetOffset() 
        { 
            Point offset = new Point();
            FrameworkElement target = ExtensionSurface.GetPlacementTarget(this); 
            if (null != target)
            {
                FrameworkElement commonRoot = target.FindCommonVisualAncestor(this) as FrameworkElement;
                MatrixTransform transform = (MatrixTransform)target.TransformToAncestor(commonRoot); 
                Point targetPosition = transform.Transform(new Point());
                Point windowPosition = ExtensionSurface.GetPosition(this); 
                offset.X = targetPosition.X - windowPosition.X; 
                offset.Y = targetPosition.Y - windowPosition.Y;
            } 
            return offset;
        }

 
        static void OnDataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        { 
            ((ExtensionWindow)sender).OnDataChanged(args.OldValue, args.NewValue); 
        }
 
        static void OnPositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((ExtensionWindow)sender).OnPositionChanged((Point)args.NewValue);
        } 

        static void OnVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        { 
            ((ExtensionWindow)sender).OnVisibilityChanged((Visibility)e.OldValue, (Visibility)e.NewValue);
        } 

        protected override void OnVisualParentChanged(DependencyObject oldParent)
        {
            base.OnVisualParentChanged(oldParent); 
            ExtensionWindow dummy;
            if (!DesignerProperties.GetIsInDesignMode(this) && !TryGetParentExtensionWindow(this, out dummy, out this.surface)) 
            { 
                Fx.Assert(string.Format(CultureInfo.InvariantCulture, "ExtensionWindow '{0}' cannot be used outside ExtensionSurface", this.Name));
            } 
        }

        protected virtual void OnDataChanged(object oldData, object newData)
        { 
        }
 
        protected virtual void OnVisibilityChanged(Visibility oldValue, Visibility newValue) 
        {
            RaiseEvent(new RoutedEventArgs(VisibilityChangedEvent, this)); 
        }

        protected virtual void OnPositionChanged(Point position)
        { 
            if (null != this.surface)
            { 
                this.surface.SetWindowPosition(this, position); 
            }
        } 

        public bool TryFindElement(string elementName, out object element)
        {
            //helper method - it looks for named visual elements in the template provided by the user 
            element = null;
            if (null != this.presenter) 
            { 
                element = this.presenter.ContentTemplate.FindName(elementName, this.presenter);
            } 
            return (null != element);
        }

        public override void OnApplyTemplate() 
        {
            base.OnApplyTemplate(); 
            //lookup for content presenter (should always be there) 
            this.presenter = this.Template.FindName("PART_Content", this) as ContentPresenter;
            if (!DesignerProperties.GetIsInDesignMode(this) && null != this.presenter && null == this.presenter.Content) 
            {
                //setup bindings - datacontext and content may possibly change, so i want them beeing set via databinding
                Binding binding = new Binding();
                binding.Source = this; 
                this.presenter.SetBinding(ContentPresenter.ContentProperty, binding);
                binding = new Binding(); 
                binding.Source = this; 
                this.presenter.SetBinding(ContentPresenter.DataContextProperty, binding);
                this.presenter.ApplyTemplate(); 
            }
            this.border = this.Template.FindName("PART_ShapeBorder", this) as Border;
            if (null != this.border)
            { 
                this.border.MouseMove += OnBorderMouseMove;
                this.border.MouseDown += OnBorderMouseDown; 
                this.border.MouseUp += OnBorderMouseUp; 
                this.border.MouseLeave += OnBorderMouseLeave;
            } 
        }

        static internal void RaiseWindowCloseEvent(ExtensionWindow sender)
        { 
            ExtensionWindowClosingRoutedEventArgs args = new ExtensionWindowClosingRoutedEventArgs(ClosingEvent, sender);
            sender.RaiseEvent(args); 
            if (!args.Cancel) 
            {
                sender.RaiseEvent(new RoutedEventArgs(CloseEvent, sender)); 
            }
        }

        void OnBorderMouseMove(object sender, MouseEventArgs e) 
        {
            if (!this.border.IsMouseCaptured) 
            { 
                if (this.border.IsMouseDirectlyOver && this.IsResizable && ExtensionSurface.GetMode(this) == ExtensionSurface.PlacementMode.Absolute)
                { 
                    Point position = e.GetPosition(this.border);

                    if (position.X <= BorderOffset && position.Y <= BorderOffset)
                    { 
                        this.resizeOption = ResizeValues.TopLeft;
                        Mouse.OverrideCursor = Cursors.SizeNWSE; 
                    } 
                    else if (position.X >= this.border.ActualWidth - BorderOffset && position.Y <= BorderOffset)
                    { 
                        this.resizeOption = ResizeValues.TopRight;
                        Mouse.OverrideCursor = Cursors.SizeNESW;
                    }
                    else if (position.X <= BorderOffset && position.Y >= this.border.ActualHeight - BorderOffset) 
                    {
                        this.resizeOption = ResizeValues.BottomLeft; 
                        Mouse.OverrideCursor = Cursors.SizeNESW; 
                    }
                    else if (position.X >= this.border.ActualWidth - BorderOffset && position.Y >= this.border.ActualHeight - BorderOffset) 
                    {
                        this.resizeOption = ResizeValues.BottomRight;
                        Mouse.OverrideCursor = Cursors.SizeNWSE;
                    } 
                    else if (position.Y <= (BorderOffset / 2.0))
                    { 
                        this.resizeOption = ResizeValues.Top; 
                        Mouse.OverrideCursor = Cursors.SizeNS;
                    } 
                    else if (position.Y >= this.border.ActualHeight - (BorderOffset / 2.0))
                    {
                        this.resizeOption = ResizeValues.Bottom;
                        Mouse.OverrideCursor = Cursors.SizeNS; 
                    }
                    else if (position.X <= (BorderOffset / 2.0)) 
                    { 
                        this.resizeOption = ResizeValues.Left;
                        Mouse.OverrideCursor = Cursors.SizeWE; 
                    }
                    else if (position.X >= this.border.ActualWidth - (BorderOffset / 2.0))
                    {
                        this.resizeOption = ResizeValues.Right; 
                        Mouse.OverrideCursor = Cursors.SizeWE;
                    } 
                    else 
                    {
                        Mouse.OverrideCursor = null; 
                        this.resizeOption = ResizeValues.NONE;
                    }
                    Point topLeft = ExtensionSurface.GetPosition(this);
                    this.bottomRight = new Point(topLeft.X + Width, topLeft.Y + Height); 
                }
                else if (Mouse.OverrideCursor != null) 
                { 
                    Mouse.OverrideCursor = null;
                    this.resizeOption = ResizeValues.NONE; 
                }
            }
            else if (e.LeftButton == MouseButtonState.Pressed)
            { 
                this.HandleWindowResize();
            } 
        } 

        void OnBorderMouseDown(object sender, MouseButtonEventArgs e) 
        {
            if (this.resizeOption != ResizeValues.NONE && sender == this.border)
            {
                Mouse.Capture(this.border); 
            }
        } 
 
        void OnBorderMouseUp(object sender, MouseButtonEventArgs e)
        { 
            if (this.border.IsMouseCaptured)
            {
                Mouse.Capture(null);
            } 
        }
 
        void OnBorderMouseLeave(object sender, MouseEventArgs e) 
        {
            this.resizeOption = ResizeValues.NONE; 
            Mouse.OverrideCursor = null;
        }

        void HandleWindowResize() 
        {
            switch (this.resizeOption) 
            { 
                case ResizeValues.Top:
                    CalculateSize(false, true, false, true); 
                    break;

                case ResizeValues.TopLeft:
                    CalculateSize(true, true, true, true); 
                    break;
 
                case ResizeValues.Left: 
                    CalculateSize(true, false, true, false);
                    break; 

                case ResizeValues.BottomLeft:
                    CalculateSize(true, false, true, true);
                    break; 

                case ResizeValues.TopRight: 
                    CalculateSize(false, true, true, true); 
                    break;
 
                case ResizeValues.Bottom:
                    CalculateSize(false, false, false, true);
                    break;
 
                case ResizeValues.Right:
                    CalculateSize(false, false, true, false); 
                    break; 

                case ResizeValues.BottomRight: 
                    CalculateSize(false, false, true, true);
                    break;

                default: 
                    Fx.Assert("not supported resize option " + this.resizeOption);
                    break; 
            }; 
        }
 
        void CalculateSize(bool changeX, bool changeY, bool changeWidth, bool changeHeight)
        {
            Point current = Mouse.GetPosition(this);
            Point absolutePosition = Mouse.GetPosition(this.surface); 

            Point topLeft = ExtensionSurface.GetPosition(this); 
 
            double initialHeight = this.bottomRight.Y - topLeft.Y;
            double initialWidth = this.bottomRight.X - topLeft.X; 

            Size size = new Size(initialWidth, initialHeight);

            if (changeX) 
            {
                if (bottomRight.X > absolutePosition.X) 
                { 
                    if ((double.IsNaN(MinWidth) || double.IsInfinity(MinWidth) || bottomRight.X - absolutePosition.X >= MinWidth) &&
                        (double.IsNaN(MaxWidth) || double.IsInfinity(MaxWidth) || bottomRight.X - absolutePosition.X <= MaxWidth)) 
                    {
                        size.Width = this.bottomRight.X - absolutePosition.X;
                        topLeft.X = absolutePosition.X;
                    } 
                }
            } 
            else 
            {
                if (changeWidth) 
                {
                    size.Width = Math.Min(Math.Max(MinWidth, current.X), MaxWidth);
                }
            } 
            if (changeY)
            { 
                if (bottomRight.Y > absolutePosition.Y) 
                {
                    if ((double.IsNaN(MinHeight) || double.IsInfinity(MinHeight) || bottomRight.Y - absolutePosition.Y >= MinHeight) && 
                        (double.IsNaN(MaxHeight) || double.IsInfinity(MaxHeight) || bottomRight.Y - absolutePosition.Y <= MaxHeight))
                    {
                        size.Height = this.bottomRight.Y - absolutePosition.Y;
                        topLeft.Y = absolutePosition.Y; 
                    }
                } 
            } 
            else
            { 
                if (changeHeight)
                {
                    size.Height = Math.Min(Math.Max(MinHeight, current.Y), MaxHeight);
                } 
            }
            if (changeX || changeY) 
            { 
                this.surface.SetWindowPosition(this, topLeft);
            } 
            this.surface.SetSize(this, size);
        }

        protected override void OnKeyDown(KeyEventArgs e) 
        {
            //if ESC - close me 
            if (e.Key == Key.Escape) 
            {
                RaiseWindowCloseEvent(this); 
            }
            base.OnKeyDown(e);
        }
 
        protected override void OnMouseDown(MouseButtonEventArgs e)
        { 
            base.OnMouseDown(e); 
            this.SelectWindow();
        } 



        public void SelectWindow() 
        {
            this.surface.SelectWindow(this); 
        } 

        void OnMenuItemsChanged(object sender, NotifyCollectionChangedEventArgs e) 
        {
            if (null != e.NewItems)
            {
                foreach (MenuItem item in e.NewItems) 
                {
                    item.DataContext = this; 
                } 
            }
        } 


        internal static bool TryGetParentExtensionWindow(FrameworkElement element, out ExtensionWindow window, out ExtensionSurface surface)
        { 
            window = null;
            surface = null; 
            if (null != element) 
            {
                FrameworkElement current = element; 
                window = element.TemplatedParent as ExtensionWindow;
                while (null == window && null != current)
                {
                    window = current as ExtensionWindow; 
                    current = (FrameworkElement)current.Parent;
                } 
                if (null != window) 
                {
                    current = window; 
                    surface = window.TemplatedParent as ExtensionSurface;
                    while (null == surface && null != current)
                    {
                        surface = current as ExtensionSurface; 
                        current = (FrameworkElement)current.Parent;
                    } 
                } 
            }
            return (null != window && null != surface); 
        }

        enum ResizeValues
        { 
            NONE,
            TopLeft, 
            Left, 
            BottomLeft,
            Bottom, 
            BottomRight,
            Right,
            TopRight,
            Top, 
        };
    } 
} 

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