您的位置:首页 > 其它

How to change size of WPF controls at runtime

2013-11-11 09:01 399 查看
from:
http://denismorozov.blogspot.com/2008/01/how-to-resize-wpf-controls-at-runtime.html


How to change size of WPF controls at runtime

This sample code uses mouse events to change the size UI elements on Canvas. Stretching is only done for usual bottom,
right and bottom-right of the control - you can do top and left in a similar fashion. For controls I used 3 rectangles (actually borders containing rectangles). All three controls
are identical except for the names. Note, that each has a TranslateTransform in the TransformGroup. The C# code uses LINQ
query
to get the right transform from the group before applying new coordinates to it for dragging. This sample also includes the changing of the Z Order to maintain the control that is on top.

Check out a short video below XAML code. It shows what compiled XAML looks like and demostrates dragging and resizing.

* * * * * * * * * * * * *

* Here's the XAML code: *

* * * * * * * * * * * * *

<Window x:Class="MoveObjectOnMouseDownUpMove.Window1"

    xmlns="/winfx/2006/xaml/presentation"
    xmlns:x="/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
        <Canvas x:Name="canvas" MouseMove="Canvas_MouseMove">

        <Border Name="border1" Canvas.Left="123" Canvas.Top="35"
                BorderBrush="DarkKhaki" BorderThickness="1"  CornerRadius="5" Padding="5"
                Height="68" Width="68" MinHeight="10" MinWidth="10"
                MouseLeftButtonDown="border_MouseLeftButtonDown"
                MouseLeave="border_MouseLeave"
                MouseEnter="border_MouseEnter">
            <Border.BitmapEffect>
                <DropShadowBitmapEffect Color="DarkGray"/>

            </Border.BitmapEffect>
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Border.RenderTransform>
            <Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>

        </Border>
        <Border Name="border2" Canvas.Left="123" Canvas.Top="35"
                BorderBrush="DarkKhaki" BorderThickness="1"  CornerRadius="5" Padding="5"
                Height="68" Width="68" MinHeight="10" MinWidth="10"
                MouseLeftButtonDown="border_MouseLeftButtonDown"
                MouseLeave="border_MouseLeave"
                MouseEnter="border_MouseEnter">
            <Border.BitmapEffect>
                <DropShadowBitmapEffect Color="DarkGray"/>
            </Border.BitmapEffect>
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Border.RenderTransform>
            <Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>

        </Border>
        <Border Name="border3" Canvas.Left="123" Canvas.Top="35"
                BorderBrush="DarkKhaki" BorderThickness="1"  CornerRadius="5" Padding="5"
                Height="68" Width="68" MinHeight="10" MinWidth="10"
                MouseLeftButtonDown="border_MouseLeftButtonDown"
                MouseLeave="border_MouseLeave"
                MouseEnter="border_MouseEnter">
            <Border.BitmapEffect>
                <DropShadowBitmapEffect Color="DarkGray"/>
            </Border.BitmapEffect>
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Border.RenderTransform>
            <Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>
        </Border>
            </Canvas>
</Window>


When you compile XAML Code, it will look the image below. Before starting to go into C# file to add logic to the events created in XAML, check out the video to see the dragging,
resizing and maintaining of the z Order.




* * * * * * * * * * * * * * * * * * *

Here's the C# code

* * * * * * * * * * * * * * * * * * *

public partial class Window1 : Window
    {
        private Element current = new Element();
        public Window1()
        {
            InitializeComponent();
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            this.current.X = Mouse.GetPosition(this.canvas).X;
            this.current.Y = Mouse.GetPosition(this.canvas).Y;

            if(this.current.InputElement != null)
                this.current.InputElement.CaptureMouse();

            if (!this.current.IsStretching)
                this.current.IsDragging = true;
        }
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);

            if (this.current.InputElement != null)
                this.current.InputElement.ReleaseMouseCapture();

            this.Cursor = Cursors.Arrow;
        }

        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if ( e.LeftButton == MouseButtonState.Pressed &&
                 current.InputElement != null)
            {
                //increment z-Order and pass it to the current element, 
                //so that it stays on top of all other elements
                ((Border)this.current.InputElement).SetValue(Canvas.ZIndexProperty, this.current.ZIndex++);

                if (this.current.IsDragging)
                    Drag(sender);

                if (this.current.IsStretching)
                    Stretch(sender);
            }
        }

        private void border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //capture the last highest z index before pointing to new current element
            int newZIndex = (int)((Border)sender).GetValue(Canvas.ZIndexProperty);
            this.current.ZIndex = newZIndex > this.current.ZIndex ? newZIndex : this.current.ZIndex;

            //capture the new current element
            this.current.InputElement = (IInputElement)sender;
        }
        private void border_MouseLeave(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
                return;

            // get coordinates
            Border border = (Border)sender;
            var rightLimit = border.ActualWidth - border.Padding.Right;
            var bottomLimit = border.ActualHeight - border.Padding.Bottom;
            var x = Mouse.GetPosition((IInputElement)sender).X;
            var y = Mouse.GetPosition((IInputElement)sender).Y;

            // figure out stretching directions - only to Right, Bottom 
            bool stretchRight = (x >= rightLimit && x < border.ActualWidth) ? true : false;
            bool stretchBottom = (y >= bottomLimit && y < border.ActualHeight) ? true : false;

            // update current element
            this.current.InputElement = (IInputElement)sender;
            this.current.X = x;
            this.current.Y = y;
            this.current.IsStretching = true;

            //set cursor to show stretch direction 
            if (stretchRight && stretchBottom)
            {
                this.Cursor = Cursors.SizeNWSE;
                return;
            }
            else if (stretchRight && !stretchBottom)
            {
                this.Cursor = Cursors.SizeWE;
                return;
            }
            else if (stretchBottom && !stretchRight)
            {
                this.Cursor = Cursors.SizeNS;
                return;
            }
            else //no stretch
            {
                this.Cursor = Cursors.Arrow;
                this.current.IsStretching = false;
            }
        }
        private void border_MouseEnter(object sender, MouseEventArgs e)
        {
            Border border = (Border)sender;

            var rightLimit = border.ActualWidth - border.Padding.Right;
            var bottomLimit = border.ActualHeight - border.Padding.Bottom;

            var x = Mouse.GetPosition((IInputElement)sender).X;
            var y = Mouse.GetPosition((IInputElement)sender).Y;

            if (x < rightLimit && y < bottomLimit)
                this.Cursor = Cursors.Arrow;
        }

        private void Drag(object sender)
        {
            this.Cursor = Cursors.Hand;

            // Retrieve the current position of the mouse.
            var newX = Mouse.GetPosition((IInputElement)sender).X;
            var newY = Mouse.GetPosition((IInputElement)sender).Y;

            // Reset the location of the object (add to sender's renderTransform newPosition minus currentElement's position
            var transformGroup = ((UIElement)this.current.InputElement).RenderTransform as TransformGroup;
            if (transformGroup == null)
                return;

            var translateTransforms = from transform in transformGroup.Children
                                      where transform.GetType().Name == "TranslateTransform"
                                      select transform;

            foreach (TranslateTransform tt in translateTransforms)
            {
                tt.X += newX - current.X;
                tt.Y += newY - current.Y;
            }

            // Update the beginning position of the mouse
            current.X = newX;
            current.Y = newY;
        }
        private void Stretch(object sender)
        {

            // Retrieve the current position of the mouse.
            var mousePosX = Mouse.GetPosition((IInputElement)sender).X;
            var mousePosY = Mouse.GetPosition((IInputElement)sender).Y;

            //get coordinates
            Border border = (Border)this.current.InputElement;
            var xDiff = mousePosX - this.current.X;
            var yDiff = mousePosY - this.current.Y;
            var width = ((Border)this.current.InputElement).Width;
            var heigth = ((Border)this.current.InputElement).Height;

            //make sure not to resize to negative width or heigth
            xDiff = (border.Width + xDiff) > border.MinWidth ? xDiff : border.MinWidth;
            yDiff = (border.Height + yDiff) > border.MinHeight ? yDiff : border.MinHeight;

            // stretchRight && stretchBottom ?
            if (this.Cursor == Cursors.SizeNWSE)
            {
                ((Border)this.current.InputElement).Width += xDiff;
                ((Border)this.current.InputElement).Height += yDiff;
            }
            // stretchRight ? 
            else if (this.Cursor == Cursors.SizeWE)
                ((Border)this.current.InputElement).Width += xDiff;

            // stretchBottom ?
            else if (this.Cursor == Cursors.SizeNS)
                ((Border)this.current.InputElement).Height += yDiff;

            //no stretch
            else
            {
                this.Cursor = Cursors.Arrow;
                this.current.IsStretching = false;
            }

            // update current coordinates with the latest postion of the mouse
            this.current.X = mousePosX;
            this.current.Y = mousePosY;
        }
    }

    public class Element
    {
        #region Fields
        private bool isDragging = false;
        private bool isStretching = false;
        private bool stretchLeft = false;
        private bool stretchRight = false;
        private IInputElement inputElement = null;
        private double x, y = 0;
        private int zIndex = 0;
        #endregion

        #region Constructor
        public Element(){}
        #endregion

        #region Properties
        public IInputElement InputElement
        {
            get { return this.inputElement; }
            set
            {
                this.inputElement = value;
                this.isDragging = false;
                this.isStretching = false;
            }
        }
        public double X
        {
            get { return this.x; }
            set { this.x = value; }
        }
        public double Y
        {
            get { return this.y; }
            set { this.y = value; }
        }
        public int ZIndex
        {
            get { return this.zIndex; }
            set { this.zIndex = value; }
        }
        public bool IsDragging
        {
            get { return this.isDragging; }
            set
            {
                this.isDragging = value;
                this.isStretching = !this.isDragging;
            }
        }
        public bool IsStretching
        {
            get { return this.isStretching; }
            set
            {
                this.isStretching = value;
                this.IsDragging = !this.isStretching;
            }
        }
        public bool StretchLeft
        {
            get { return this.stretchLeft; }
            set { this.stretchLeft = value; this.stretchRight = !this.stretchLeft; }
        }
        public bool StretchRight
        {
            get { return this.stretchRight; }
            set { this.stretchRight = value; this.stretchLeft = !this.stretchRight; }
        }
        #endregion
    }
}
_________________________________________________________________

end of post
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: