wpf在窗口的控件拖动、点击窗口中控件显示在最上面以及控件拖动不超过窗口边界

刚开始从网上找了一个只可以完成拖动,而且控件必须设置为水平为left、垂直为top才能正常移动,因此很不方便,所以就在此基础上修改了一下代码,然后不管设置任何水平和垂直都可以完成拖动,后来又有了新的需求,拖动时会超过边界,刚开始弄了半天实现了没有设置水平和垂直的控件,设置了水平和垂直只能在设置了的方向才能移动,弄了一周在窗口不改变大小的情况可以正常实现了,但是一放大窗口又不行了,就在之前的代码上改,结果发现一句代码就实现了,之前写的代码都是无用功的,走了弯路,因此写下这篇博客,希望后面的小伙伴不要走同样的弯路。主要代码如下。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;


namespace WpfComboBox.Entity
{
    public class InitDrag
    {
        private int totalZIndex = 100;
        private IEnumerable<UIElement> DragElements { get; set; }
        private FrameworkElement WindowElement;
        public void Drag(IEnumerable<UIElement> dragElements, FrameworkElement windowElement)
        {
            WindowElement = windowElement;
            DragElements = dragElements;
            //WPF设计上的问题,Button.Clicked事件Supress掉了Mouse.MouseLeftButtonDown附加事件等.
            //不加这个Button、TextBox等无法拖动
            foreach (UIElement uiEle in DragElements)
            {
                uiEle.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                uiEle.AddHandler(Button.MouseMoveEvent, new MouseEventHandler(Element_MouseMove), true);
                uiEle.AddHandler(Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);
            }
        }


        bool isDragDropInEffect = false;
        Point pos = new Point();
        void Element_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement currEle = sender as FrameworkElement;
                double xPos = e.GetPosition(null).X - pos.X + currEle.Margin.Left;
                double yPos = e.GetPosition(null).Y - pos.Y + currEle.Margin.Top;
                double rPos = pos.X - e.GetPosition(null).X + currEle.Margin.Right;
                double bPos = pos.Y - e.GetPosition(null).Y + currEle.Margin.Bottom;
                if (xPos >= 0 && rPos >= 0 && yPos >= 0 && bPos >= 0)
                {
                    currEle.Margin = new Thickness(xPos, yPos, rPos, bPos);
                }
                pos = e.GetPosition(null);
            }
        }
        void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement fEle = sender as FrameworkElement;
            totalZIndex++;
            Canvas.SetZIndex(fEle, totalZIndex);
            isDragDropInEffect = true;
            pos = e.GetPosition(null);
            fEle.CaptureMouse();
            fEle.Cursor = Cursors.Hand;
            SetMargin(fEle);
        }
        /// <summary>
        /// 设置上下左右边距
        /// </summary>
        /// <param name="fEle"></param>
        private void SetMargin(FrameworkElement fEle)
        {   
            //取得控件在窗口中的坐标
            Window wind = Window.GetWindow(fEle);
            Point point = fEle.TransformToAncestor(wind).Transform(new Point(0, 0));
            //得到窗体的标题高度和窗口外边宽度
            var verticalBorderWidth = SystemParameters.ResizeFrameVerticalBorderWidth;
            var titleHeight = SystemParameters.WindowCaptionHeight + SystemParameters.ResizeFrameHorizontalBorderHeight;
            double x = point.X;
            double y = point.Y;
            double right = WindowElement.ActualWidth - fEle.ActualWidth - x - 4 * verticalBorderWidth;
            double bottom = WindowElement.ActualHeight - fEle.ActualHeight - y - titleHeight - 3 * verticalBorderWidth;
            fEle.Margin = new Thickness(x, y, right, bottom);
        }


        void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isDragDropInEffect)
            {
                FrameworkElement ele = sender as FrameworkElement;
                isDragDropInEffect = false;
                ele.ReleaseMouseCapture();
            }
        }
    }
}

在wpf窗体中使用的代码:

namespace WpfComboBox
{
    /// <summary>
    /// Window3.xaml 的交互逻辑
    /// </summary>
    public partial class Window3 : Window
    {
        public Window3()
        {
            InitializeComponent();
            InitDrag  initDrag=new InitDrag();
            var DragElements = new List<UIElement>() { button1, button2, Grid, label1, Grid1,button };
            initDrag.Drag(DragElements, Window);

       }

    }

}

posted on 2017-04-25 23:05  一只小小的程序猿  阅读(1803)  评论(0编辑  收藏  举报