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

2022-06-09 11:17:08 浏览数 (1)

在之前写了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

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

0 人点赞