How to change size of WPF controls at runtime

22 篇文章 0 订阅

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值