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);

       }

    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM