前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【NEW】WPF窗体中控件移动 + 拖拽大小 + 动画拖动

【NEW】WPF窗体中控件移动 + 拖拽大小 + 动画拖动

作者头像
Shunnet
发布2022-06-09 11:17:08
1.8K1
发布2022-06-09 11:17:08
举报
在之前写了WPF窗体中控件移动 + 拖拽大小 + 动画拖动,但是只能在Canvas容器布局中使用

现在,新增可以在GRID中可以动画拖动了
【GRID中实现动画效果】

【Canvas实现动画效果】

上菜【一定要给需要动态拖动的控件设置宽高】
代码语言:javascript
复制
/*
       注意:只要不带焦点的控件包括用户控件 都可以拖动与拖拽大小   【基类中的【公共参数】可以自行修改哦】
       使用方法[这是在一个窗体的后台代码]:
       //实例化对象
       public DragControlsHelper dragControlsHelper = new DragControlsHelper();

       //执行以下方法就可以拖拽了[this属于窗体的对象,小范围拖拽可以自建布局容器]
       dragControlsHelper.Insert(控件的对象或者控件的Name, this);

       //移除拖拽大小与移动也很简单
       dragControlsHelper.Remove(控件的对象或者控件的Name);

       //WPF中布局容器有6种如下:
       [Grid]网格布局,其中控件或容器需指定位置;
       [StackPanel]堆叠面板,其中的控件水平布局、竖直布局;
       [DockPanel]停靠面板,内部控件或容器可以放置在上、下、左、右;
       [WrapPanel]可以看作是具有自动换行功能的StackPanel容器。窗体太小时,其末尾的控件会自动换行,像Java中的流布局;
       [Canvas]坐标布局,基于坐标的布局,利用Canvas.Left,Canvas.Top,Canvas.Right,Canvas.Bottom这四个附加属性来定位控件坐标;
       [UniformGrid]指定行和列的数量, 均分有限的容器空间。

       //by:Shunnet.top 2022/5/18
    */
    /// <summary>
    /// 控件拖动基类
    /// </summary>
    public class DragControlsBase : Adorner
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Controls">要拖动的控件</param>
        /// <param name="LlayoutContainer">窗体的布局容器</param>
        public DragControlsBase(UIElement Controls, FrameworkElement LlayoutContainer) : base(Controls)
        {
            this.Controls = Controls;
            this.LlayoutContainer = LlayoutContainer;

            InitDragDelta();  //初始化拖动大小

            InitMove();  //初始化移动
        }
        /// <summary>
        /// 容器边框颜色
        /// </summary>
        public SolidColorBrush BorderColor = new SolidColorBrush(Colors.Green);
        /// <summary>
        /// 容器边框线径
        /// </summary>
        public Thickness BorderWireDiameter = new Thickness(1);
        /// <summary>
        /// 容器边框透明度
        /// </summary>
        public double BorderOpacity = 0;
        /// <summary>
        /// 拖拽装饰器的内圈颜色
        /// </summary>
        public SolidColorBrush ThumbInnerColor = new SolidColorBrush(Colors.Red);
        /// <summary>
        /// 拖拽装饰器的外圈颜色
        /// </summary>
        public SolidColorBrush ThumbOuterColor = new SolidColorBrush(Colors.Red);
        /// <summary>
        /// 装饰器线径
        /// </summary>
        public double ThumbWireDiameter = 1;
        /// <summary>
        /// 装饰器透明度
        /// </summary>
        public double ThumbOpacity = 0.6;
        /// <summary>
        /// 拖拽最小的宽
        /// </summary>
        public double MinWidth = 100;
        /// <summary>
        /// 拖拽最小的高
        /// </summary>
        public double MinHeight = 100;
        /// <summary>
        /// 拖拽最大的宽
        /// </summary>
        public double MaxWidth = 500;
        /// <summary>
        /// 拖拽最大的高
        /// </summary>
        public double MaxHeight = 500;

        #region 私有字段
        /// <summary>
        /// 4条边
        /// </summary>
        Thumb LeftThumb, TopThumb, RightThumb, BottomThumb;
        /// <summary>
        /// 4个角
        /// </summary>
        Thumb LefTopThumb, RightTopThumb, RightBottomThumb, LeftbottomThumb;
        /// <summary>
        /// 中间  目前暂不使用
        /// </summary>
        Thumb CentreThumb;
        /// <summary>
        /// 布局容器,如果不使用布局容器,则需要给上述8个控件布局,实现和Grid布局定位是一样的,会比较繁琐且意义不大。
        /// </summary>
        Grid Llayout;
        /// <summary>
        /// 要拖动的控件
        /// </summary>
        UIElement Controls;
        /// <summary>
        /// 窗体的布局容器
        /// </summary>
        FrameworkElement LlayoutContainer;
        /// <summary>
        /// 鼠标是否按下
        /// </summary>
        bool IsMouseDown = false;
        /// <summary>
        /// 鼠标按下的位置
        /// </summary>
        Point MouseDownPosition;
        /// <summary>
        /// 鼠标按下控件的Margin
        /// </summary>
        Thickness MouseDownMargin;
        #endregion

        #region 重写方法
        protected override Visual GetVisualChild(int index)
        {
            return Llayout;
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return 1;
            }
        }
        protected override Size ArrangeOverride(Size finalSize)
        {
            //直接给容器布局,容器内部的装饰器会自动布局。
            Llayout.Arrange(new Rect(new Point(-LeftThumb.Width / 2, -LeftThumb.Height / 2), new Size(finalSize.Width + LeftThumb.Width, finalSize.Height + LeftThumb.Height)));
            return finalSize;
        }
        #endregion

        #region 方法
        /// <summary>
        /// 初始化拖拽大小
        /// </summary>
        public void InitDragDelta()
        {
            //初始化装饰器
            LeftThumb = new Thumb();
            LeftThumb.HorizontalAlignment = HorizontalAlignment.Left;
            LeftThumb.VerticalAlignment = VerticalAlignment.Center;
            LeftThumb.Cursor = Cursors.SizeWE;
            TopThumb = new Thumb();
            TopThumb.HorizontalAlignment = HorizontalAlignment.Center;
            TopThumb.VerticalAlignment = VerticalAlignment.Top;
            TopThumb.Cursor = Cursors.SizeNS;
            RightThumb = new Thumb();
            RightThumb.HorizontalAlignment = HorizontalAlignment.Right;
            RightThumb.VerticalAlignment = VerticalAlignment.Center;
            RightThumb.Cursor = Cursors.SizeWE;
            BottomThumb = new Thumb();
            BottomThumb.HorizontalAlignment = HorizontalAlignment.Center;
            BottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
            BottomThumb.Cursor = Cursors.SizeNS;
            LefTopThumb = new Thumb();
            LefTopThumb.HorizontalAlignment = HorizontalAlignment.Left;
            LefTopThumb.VerticalAlignment = VerticalAlignment.Top;
            LefTopThumb.Cursor = Cursors.SizeNWSE;
            RightTopThumb = new Thumb();
            RightTopThumb.HorizontalAlignment = HorizontalAlignment.Right;
            RightTopThumb.VerticalAlignment = VerticalAlignment.Top;
            RightTopThumb.Cursor = Cursors.SizeNESW;
            RightBottomThumb = new Thumb();
            RightBottomThumb.HorizontalAlignment = HorizontalAlignment.Right;
            RightBottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
            RightBottomThumb.Cursor = Cursors.SizeNWSE;
            LeftbottomThumb = new Thumb();
            LeftbottomThumb.HorizontalAlignment = HorizontalAlignment.Left;
            LeftbottomThumb.VerticalAlignment = VerticalAlignment.Bottom;
            LeftbottomThumb.Cursor = Cursors.SizeNESW;
            CentreThumb = new Thumb();
            CentreThumb.HorizontalAlignment = HorizontalAlignment.Center;
            CentreThumb.VerticalAlignment = VerticalAlignment.Center;
            CentreThumb.Cursor = Cursors.SizeAll;
            Llayout = new Grid();
            //给布局容器加个边框
            Border border = new Border();
            border.Margin = new Thickness(2);
            border.Opacity = BorderOpacity;
            border.BorderThickness = BorderWireDiameter;
            border.BorderBrush = BorderColor;
            Llayout.Children.Add(border);
            //给布局容器添加拖动大小装饰器
            Llayout.Children.Add(LeftThumb);
            Llayout.Children.Add(TopThumb);
            Llayout.Children.Add(RightThumb);
            Llayout.Children.Add(BottomThumb);
            Llayout.Children.Add(LefTopThumb);
            Llayout.Children.Add(RightTopThumb);
            Llayout.Children.Add(RightBottomThumb);
            Llayout.Children.Add(LeftbottomThumb);
            //Llayout.Children.Add(CentreThumb);   //中间的装饰器 暂不使用
            AddVisualChild(Llayout);
            foreach (var item in Llayout.Children)
            {
                if (item.GetType().Equals(typeof(Thumb)))
                {
                    Thumb thumb = item as Thumb;
                    thumb.Width = 5;   //设置圆圈的宽
                    thumb.Height = 5;  //设置圆圈的高
                    thumb.Opacity = ThumbOpacity;//透明度
                    thumb.Template = new ControlTemplate(typeof(Thumb))   //模板
                    {
                        VisualTree = GetFactory(ThumbInnerColor, ThumbOuterColor, ThumbWireDiameter)
                    };
                    thumb.DragDelta += Control_DragDelta;
                }
            }
        }
        /// <summary>
        /// 装饰器样式
        /// </summary>
        /// <param name="InnerColor">内圈颜色</param>
        /// <param name="OuterColor">外圈颜色</param>
        /// <param name="WireDiameter">线径</param>
        /// <param name="Opacity">透明度</param>
        /// <returns></returns>
        FrameworkElementFactory GetFactory(Brush InnerColor, Brush OuterColor, double WireDiameter)
        {
            FrameworkElementFactory Element = new FrameworkElementFactory(typeof(Ellipse));  //绘制椭圆形元素
            Element.SetValue(Ellipse.FillProperty, InnerColor);  //内圈色
            Element.SetValue(Ellipse.StrokeProperty, OuterColor);  //外圈色
            Element.SetValue(Ellipse.StrokeThicknessProperty, WireDiameter);   //线径
            return Element;
        }

        /// <summary>
        /// 初始化移动
        /// </summary>
        public void InitMove()
        {
            //添加移动事件
            Controls.MouseLeftButtonDown += Control_MouseLeftButtonDown;   //鼠标左键按下
            Controls.MouseLeftButtonUp += Control_MouseLeftButtonUp;   //鼠标左键松开
            Controls.MouseMove += Control_MouseMove;   //鼠标移动
        }
        #endregion

        #region 事件
        //拖拽大小逻辑
        private void Control_DragDelta(object sender, DragDeltaEventArgs e)
        {
            FrameworkElement Control = Controls as FrameworkElement;  //要拖动的控件
            FrameworkElement Thumb = sender as FrameworkElement;  //哪个装饰被拖动
            double Left, Top, Right, Bottom, Width, Height;   //左,上,右,下,宽,高
            if (Thumb.HorizontalAlignment == HorizontalAlignment.Left)
            {
                Right = Control.Margin.Right;
                Left = Control.Margin.Left + e.HorizontalChange;
                Width = (double.IsNaN(Control.Width) ? Control.ActualWidth : Control.Width) - e.HorizontalChange;
            }
            else
            {
                Left = Control.Margin.Left;
                Right = Control.Margin.Right - e.HorizontalChange;
                Width = (double.IsNaN(Control.Width) ? Control.ActualWidth : Control.Width) + e.HorizontalChange;
            }
            if (Thumb.VerticalAlignment == VerticalAlignment.Top)
            {
                Bottom = Control.Margin.Bottom;
                Top = Control.Margin.Top + e.VerticalChange;
                Height = (double.IsNaN(Control.Height) ? Control.ActualHeight : Control.Height) - e.VerticalChange;
            }
            else
            {
                Top = Control.Margin.Top;
                Bottom = Control.Margin.Bottom - e.VerticalChange;
                Height = (double.IsNaN(Control.Height) ? Control.ActualHeight : Control.Height) + e.VerticalChange;
            }

            if (Thumb.HorizontalAlignment != HorizontalAlignment.Center)
            {
                if (Width >= 0)
                {
                    if (Width >= MinWidth && Width <= MaxWidth)
                    {
                        Control.Margin = new Thickness(Left, Control.Margin.Top, Right, Control.Margin.Bottom);
                        Control.Width = Width;
                    }
                }
            }
            if (Thumb.VerticalAlignment != VerticalAlignment.Center)
            {
                if (Height >= 0)
                {
                    if (Height >= MinHeight && Height <= MaxHeight)
                    {
                        Control.Margin = new Thickness(Control.Margin.Left, Top, Control.Margin.Right, Bottom);
                        Control.Height = Height;
                    }
                }
            }
        }

        //鼠标左键按下
        private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var c = sender as FrameworkElement;
            IsMouseDown = true;
            MouseDownPosition = e.GetPosition(LlayoutContainer);
            MouseDownMargin = c.Margin;
            c.CaptureMouse();
        }
        //鼠标左键松开
        private void Control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var c = sender as FrameworkElement;
            IsMouseDown = false;
            c.ReleaseMouseCapture();
        }
        //鼠标移动
        private void Control_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsMouseDown)
            {
                var c = sender as FrameworkElement;
                var pos = e.GetPosition(LlayoutContainer);
                var dp = pos - MouseDownPosition;
                double Left, Top, Right, Bottom;  //设置控件坐标
                Left = MouseDownMargin.Left + dp.X;
                Top = MouseDownMargin.Top + dp.Y;
                Right = MouseDownMargin.Right - dp.X;
                Bottom = MouseDownMargin.Bottom - dp.Y;
                c.Margin = new Thickness(Left, Top, Right, Bottom);

                //GeneralTransform generalTransform = c.TransformToAncestor(LlayoutContainer);
                //Point point = generalTransform.Transform(new Point(0, 0));
                ////控件的  左上右下
                //double ControlLeft = c.Margin.Left;   //左
                //double ControlTop = c.Margin.Top;     //上
                //double ControlRight = point.X + c.Width;   //右
                //double ControlBottom = point.Y + c.Height;  //下
            }
        }
        #endregion
    }
    /// <summary>
    /// 控件拖动实现类
    /// </summary>
    public class DragControlsHelper
    {
        /// <summary>
        /// 数据字典
        /// UIElement:要拖动的控件
        /// AdornerLayer:装饰器
        /// DragControlsBase:装饰器实现类
        /// </summary>
        Dictionary<UIElement, Tuple<AdornerLayer, DragControlsBase>> DictionaryDataList = new Dictionary<UIElement, Tuple<AdornerLayer, DragControlsBase>>();
        /// <summary>
        /// 添加项
        /// </summary>
        /// <param name="Controls">控件</param>
        /// <param name="LlayoutContainer">窗体的布局容器:意思就是这个控件是被谁包这的就传它,我一般传窗体对象,窗体包着所有的控件,小范围拖动,自行建布局容器包着要拖动的控件 </param>
        public void Insert(UIElement Controls, FrameworkElement LlayoutContainer)
        {
            if (!DictionaryDataList.ContainsKey(Controls))
            {
                DragControlsBase dragControlsBase = new DragControlsBase(Controls, LlayoutContainer);
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(Controls);
                adornerLayer.Add(dragControlsBase);
                Tuple<AdornerLayer, DragControlsBase> tuple = new Tuple<AdornerLayer, DragControlsBase>(adornerLayer, dragControlsBase);
                DictionaryDataList.Add(Controls, tuple);
            }
        }
        /// <summary>
        /// 移除拖动
        /// </summary>
        /// <param name="Controls">控件</param>
        public void Remove(UIElement Controls)
        {
            if (DictionaryDataList.ContainsKey(Controls))
            {
                DictionaryDataList[Controls].Item1.Remove(DictionaryDataList[Controls].Item2);  //移除此项属性
                Delete(Controls);   //在集合移除此项
            }
        }
        /// <summary>
        /// 删除此项
        /// </summary>
        /// <param name="Controls">控件</param>
        private void Delete(UIElement Controls)
        {
            DictionaryDataList.Remove(Controls);  //直接移除
        }
    }

    /*
     动画拖动,包含了控件的移动与缩放大小
     注意: 单个窗体中只能定义一个布局容器,这个布局容器,不能设置Margin,不能设置固定宽高
     by:Shunnet.top 2022/6/8
    -----------------------------下面是使用方法---------------------------
     */

    #region 后端代码
    /*
    	/// <summary>
        /// 三合一
        /// 单个窗体中只能定义一个布局容器,这个布局容器,不能设置Margin,不能设置固定宽高
        /// </summary>
        DragControlsAnimate dragControlsAnimate;
        public MainWindow()
        {
            InitializeComponent();
            dragControlsAnimate = new DragControlsAnimate(this, Pane);   //你得定义一个容器传容器对象或者Name
            dragControlsAnimate.Insert(ConShow1);
            dragControlsAnimate.Insert(ConShow2);
            dragControlsAnimate.MessageEvenTrigger += MessageEvenTrigger;
            dragControlsAnimate.DragEvenTrigger += DragEvenTrigger;
        }
        /// <summary>
        /// 消息
        /// </summary>
        /// <param name="Message">消息</param>
        /// <param name="element">哪个控件显示的消息</param>
        public void MessageEvenTrigger(string Message, FrameworkElement element)
        {
            Console.WriteLine($"控件Name:{element.Name}->抛出消息:{Message}");
        }
        /// <summary>
        /// 提醒拖拽事件开始了,请传需要拖动的按钮对象
        /// </summary>
        /// <param name="element">在哪个控件上触发了拖拽</param>
        /// <returns>返回已经创建了新的控件对象  -   是否需要拖拽大小</returns>
        public (FrameworkElement NewControl, bool IsDragAndDragSize) DragEvenTrigger(FrameworkElement ShowControl)
        {
            FrameworkElement NewControl = new FrameworkElement();
            bool IsDragAndDragSize = false;
            switch (ShowControl.Name)
            {
                case "ConShow1":
                    NewControl = InitControls(0);
                    IsDragAndDragSize = false;
                    break;
                case "ConShow2":
                    NewControl = InitControls(1);
                    IsDragAndDragSize = true;
                    break;
            }
            return (NewControl, IsDragAndDragSize);
        }
        /// <summary>
        /// 创建图标
        /// </summary>
        /// <param name="dashboardDataMode">图标类型</param>
        private Label InitControls(int A)
        {
            return new Label() { Background = new SolidColorBrush(A == 0 ? Colors.AliceBlue : Colors.AntiqueWhite), Width = 100, Height = 100,Content= "自定义控件" };
        }
    */
    #endregion

    #region 前端代码
    /*
         <Window x:Class="WpfApp5.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            Title="Canvas与Grid 中拖动动画+缩放+移动 Shunnet.top" Height="500" Width="800" >
        <!--<Canvas Name="Pane" Background="DarkGray">
            <Label Content="这是使用Canvas容器布局,单个窗体中只能定义一个布局容器,这个布局容器,不能设置Margin,不能设置固定宽高" Foreground="Red" FontWeight="Bold"/>
            <Button Content="不能拖动" Width="90" Height="50" Name="ConShow1" VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="0,30,0,0"/>
            <Button Content="可以拖动" Width="90" Height="50" Name="ConShow2" VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="100,30,0,0"/>
        </Canvas>-->
        <Grid Name="Pane" Background="DarkGray">
            <Label Content="这是使用GRID容器布局,单个窗体中只能定义一个布局容器,这个布局容器,不能设置Margin,不能设置固定宽高" Foreground="Red" FontWeight="Bold"/>
            <Button Content="不能拖动" Width="90" Height="50" Name="ConShow1" VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="0,30,0,0"/>
            <Button Content="可以拖动" Width="90" Height="50" Name="ConShow2" VerticalAlignment="Top" HorizontalAlignment="Left"  Margin="100,30,0,0"/>
        </Grid>
    </Window>

     */
    #endregion

    /// <summary>
    /// 拖拽控件动画
    /// </summary>
    public class DragControlsAnimate
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Windows">窗体</param>
        /// <param name="LlayoutContainer">容器:让控件在这里面拖动</param>
        public DragControlsAnimate(FrameworkElement Windows, object LlayoutContainer)
        {
            this.Windows = Windows;
            this.LlayoutContainer = LlayoutContainer;
            Windows.SizeChanged += Windwos_SizeChanged;
        }
        #region 私有字段
        /// <summary>
        /// 界面上已经生成的控件,也就是从哪个控件上拖动的集合
        /// </summary>
        List<FrameworkElement> ShowControlsList = new List<FrameworkElement>();
        /// <summary>
        /// 窗体
        /// </summary>
        FrameworkElement Windows;
        /// <summary>
        /// 容器:让控件在这里面拖动
        /// </summary>
        object LlayoutContainer;
        /// <summary>
        /// 鼠标是否按下
        /// </summary>
        bool IsMouseDown = false;
        /// <summary>
        /// 实时需要拖动的控件
        /// </summary>
        FrameworkElement ControlsObj;
        /// <summary>
        /// 拖拽大小与移动
        /// </summary>
        DragControlsHelper dragControlsHelper = new DragControlsHelper();
        #endregion

        #region 方法

        /// <summary>
        /// 添加拖拽大小与移动
        /// </summary>
        public void DragSizeInsert(FrameworkElement Controls, FrameworkElement Window)
        {
            //创建拖动与拖拽大小
            dragControlsHelper.Insert(Controls, Window);
        }

        /// <summary>
        /// 移除拖拽大小与移动
        /// </summary>
        public void DragSizeRemove(FrameworkElement Controls)
        {
            //创建拖动与拖拽大小
            dragControlsHelper.Remove(Controls);
        }
        /// <summary>
        ///  添加需要拖动的组件
        /// </summary>
        /// <param name="ControlsShow">界面上已经生成的控件</param>
        public void Insert(FrameworkElement ControlsShow)
        {
            if (!ShowControlsList.Contains(ControlsShow))  //不存在则添加
            {
                InsertEven(ControlsShow);
                ShowControlsList.Add(ControlsShow);
            }
        }
        /// <summary>
        /// 移除拖动
        /// </summary>
        /// <param name="ControlsShow">界面上已经生成的控件</param>
        public void Remove(FrameworkElement ControlsShow)
        {
            if (ShowControlsList.Contains(ControlsShow))
            {
                RemoveEven(ControlsShow);
                ShowControlsList.Remove(ControlsShow);  //直接移除
            }
        }
        /// <summary>
        /// 创建事件
        /// </summary>
        /// <param name="ControlsShow">界面上已经生成的控件</param>
        public void InsertEven(FrameworkElement ControlsShow)
        {
            //ControlsShow.PreviewMouseLeftButtonDown += delegate (object sender, MouseButtonEventArgs e) { ControlsShow_PreviewMouseLeftButtonDown(sender, e, ControlsObj); };
            //ControlsShow.PreviewMouseLeftButtonUp += delegate (object sender, MouseButtonEventArgs e) { ControlsShow_PreviewMouseLeftButtonUp(sender, e, ControlsObj); };
            //ControlsShow.PreviewMouseMove += delegate (object sender, MouseEventArgs e) { ControlsShow_PreviewMouseMove(sender, e, ControlsObj); };

            ControlsShow.PreviewMouseLeftButtonDown += ControlsShow_PreviewMouseLeftButtonDown;
            ControlsShow.PreviewMouseLeftButtonUp += ControlsShow_PreviewMouseLeftButtonUp;
            ControlsShow.PreviewMouseMove += ControlsShow_PreviewMouseMove;
        }
        /// <summary>
        /// 移除事件
        /// </summary>
        /// <param name="ControlsShow">界面上已经生成的控件</param>
        public void RemoveEven(FrameworkElement ControlsShow)
        {
            ControlsShow.PreviewMouseLeftButtonDown -= ControlsShow_PreviewMouseLeftButtonDown;
            ControlsShow.PreviewMouseLeftButtonUp -= ControlsShow_PreviewMouseLeftButtonUp;
            ControlsShow.PreviewMouseMove -= ControlsShow_PreviewMouseMove;
        }

        #endregion

        #region 委托回调事件

        /// <summary>
        /// 定义委托 提醒拖拽事件开始了,请传需要拖动的按钮对象
        /// </summary>
        /// <param name="ShowControl">在哪个控件上触发了拖拽</param>
        /// <returns>返回已经创建了新的控件对象  -   是否需要拖拽大小</returns>
        public delegate (FrameworkElement NewControl, bool IsDragAndDragSize) dragEvenTrigger(FrameworkElement ShowControl);
        /// <summary>
        /// 实现委托
        /// </summary>
        public dragEvenTrigger DragEvenTrigger;

        /// <summary>
        /// 消息委托
        /// </summary>
        /// <param name="Message">消息</param>
        /// <param name="element">哪个控件显示的消息</param>
        public delegate void messageEvenTrigger(string Message, FrameworkElement element);
        /// <summary>
        /// 实现委托
        /// </summary>
        public messageEvenTrigger MessageEvenTrigger;
        #endregion

        #region 执行事件

        //移动位置
        private void ControlsShow_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (ControlsObj == null) return;
            if (IsMouseDown)
            {
                if (LlayoutContainer.GetType().Equals(typeof(Canvas)) )
                {
                    Point pos = e.GetPosition(Windows);
                    Canvas.SetLeft(ControlsObj, pos.X - ControlsObj.Width / 2);
                    Canvas.SetTop(ControlsObj, pos.Y - ControlsObj.Height / 2);
                }
                else if (LlayoutContainer.GetType().Equals(typeof(Grid)))
                {
                    Point pos = e.GetPosition(Windows);
                    double Left = pos.X - ControlsObj.Width / 2;
                    double Top = pos.Y - ControlsObj.Height / 2;
                    double Right = Windows.ActualWidth - Left - ControlsObj.Width;
                    double Bottom = Windows.ActualHeight - Top - ControlsObj.Height;
                    ControlsObj.Margin = new Thickness(Left, Top, Right, Bottom);
                }
            }
        }

        //当在已显示的控件左键点松开后
        private void ControlsShow_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsMouseDown = false;
            if (ControlsObj == null) return;
            ControlsObj.Opacity = 1;
            ControlsObj = null;
        }


        //当在已显示的控件左键点击后
        private void ControlsShow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (LlayoutContainer.GetType().Equals(typeof(Canvas)))
            {
                Canvas layout = LlayoutContainer as Canvas;
                (FrameworkElement element, bool IsDragAndDragSize) Data = DragEvenTrigger(sender as FrameworkElement);
                ControlsObj = Data.element;
                if (!layout.Children.Contains(ControlsObj))
                {
                    IsMouseDown = true;
                    Point Position = e.GetPosition(Windows);
                    ControlsObj.Opacity = 0.5;
                    Canvas.SetLeft(ControlsObj, Position.X - ControlsObj.Width / 2);
                    Canvas.SetTop(ControlsObj, Position.Y - ControlsObj.Height / 2);
                    layout.Children.Add(ControlsObj);
                    if (Data.IsDragAndDragSize)
                    {
                        //添加拖拽大小与移动
                        DragSizeInsert(ControlsObj, Windows);
                    }
                }
                else
                {
                    MessageEvenTrigger("此控件已在布局中存在", sender as FrameworkElement);
                    ControlsObj = null;
                }
            }
            else if (LlayoutContainer.GetType().Equals(typeof(Grid)))
            {
                Grid layout = LlayoutContainer as Grid;
                (FrameworkElement element, bool IsDragAndDragSize) Data = DragEvenTrigger(sender as FrameworkElement);
                ControlsObj = Data.element;
                if (!layout.Children.Contains(ControlsObj))
                {
                    IsMouseDown = true;
                    Point Position = e.GetPosition(Windows);
                    ControlsObj.Opacity = 0.5;

                    double Left = Position.X - ControlsObj.Width / 2;
                    double Top = Position.Y - ControlsObj.Height / 2;
                    double Right = Windows.ActualWidth - Left - ControlsObj.Width;
                    double Bottom = Windows.ActualHeight - Top - ControlsObj.Height;


                    ControlsObj.Margin = new Thickness(Left, Top, Right, Bottom);


                    layout.Children.Add(ControlsObj);
                    if (Data.IsDragAndDragSize)
                    {
                        //添加拖拽大小与移动
                        DragSizeInsert(ControlsObj, Windows);
                    }
                }
                else
                {
                    MessageEvenTrigger("此控件已在布局中存在", sender as FrameworkElement);
                    ControlsObj = null;
                }
            }
        }


        //当窗体大小改变,布局容器也要跟着改变大小
        private void Windwos_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            FrameworkElement window = sender as FrameworkElement;
            if (LlayoutContainer.GetType().Equals(typeof(Canvas)))
            {
                Canvas layout = LlayoutContainer as Canvas;
                layout.Width = window.ActualWidth;
                layout.Height = window.ActualHeight;
            }
            else if (LlayoutContainer.GetType().Equals(typeof(Grid)))
            {
                Grid layout = LlayoutContainer as Grid;
                layout.Width = window.ActualWidth;
                layout.Height = window.ActualHeight;
            }
        }
        #endregion

    }

Copy

谢谢观看

“关注[顺网]微信公众号,了解更多更有趣的实时信息”

本文作者:[博主]大顺

本文链接:https://shunnet.top/NFzYJb

版权声明:转载注明出处,谢谢

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在之前写了WPF窗体中控件移动 + 拖拽大小 + 动画拖动,但是只能在Canvas容器布局中使用
  • 现在,新增可以在GRID中可以动画拖动了
  • 【GRID中实现动画效果】
  • 【Canvas实现动画效果】
  • 上菜【一定要给需要动态拖动的控件设置宽高】
  • 谢谢观看
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档