【问题标题】:How to enable and disable dragging a button?如何启用和禁用拖动按钮?
【发布时间】:2019-07-26 07:20:06
【问题描述】:

我有一个表格。在这个表单上有一个按钮和一个面板。两者都有相同的父级:表单。我希望能够启用或禁用按钮的拖动操作。我使用的代码是:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace DraggableControls
{
    public partial class Form2 : Form
    {
        private bool isDragged;
        private Point pointOffset;

    public Form2()
    {
        InitializeComponent();

        this.Size = new System.Drawing.Size(800, 800);
        this.AllowDrop = false;

        Button button1 = new Button();
        button1.Location = new Point(50, 50);
        button1.BackColor = Color.Red;
        button1.Size = new System.Drawing.Size(80, 80);
        button1.Parent = this;
        button1.AllowDrop = false;
        button1.Draggable(false);
        this.Controls.Add(button1);

        isDragged = false;

        // For the object that will be dragged:
        button1.MouseDown += new MouseEventHandler(button1_MouseDown);
        button1.MouseMove += new MouseEventHandler(button1_MouseMove);
        button1.MouseUp += new MouseEventHandler(button1_MouseUp);

        Panel panel1 = new Panel();
        panel1.SuspendLayout();
        panel1.Location = new System.Drawing.Point(100, 100);
        panel1.Name = "panel1";
        panel1.TabIndex = 0;
        panel1.Size = new Size(500, 500);
        panel1.BackColor = Color.Green;
        panel1.AllowDrop = true;
        panel1.Parent = this;
        this.Controls.Add(panel1);
        panel1.ResumeLayout(false);

        // For the receiving object:
        panel1.DragEnter += new 
System.Windows.Forms.DragEventHandler(control_DragEnter);
        this.DragEnter += new 
System.Windows.Forms.DragEventHandler(control_DragEnter);

        this.ResumeLayout(false);
    }

    private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            if (e.Button == MouseButtons.Left)
            {
                isDragged = true;
                Point ptStartPosition = senderButton.PointToScreen(new 
Point(e.X, e.Y));

                pointOffset = new Point();
                pointOffset.X = senderButton.Location.X - ptStartPosition.X;
                pointOffset.Y = senderButton.Location.Y - ptStartPosition.Y;
            }
            else
            {
                isDragged = false;
            }
        }
    }

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            if (isDragged)
            {
                Point newPoint = senderButton.PointToScreen(new Point(e.X, 
e.Y));
                newPoint.Offset(pointOffset);
                senderButton.Location = newPoint;
            }
        }
    }

    private void button1_MouseUp(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            Point newPoint = senderButton.PointToScreen(new Point(e.X, 
e.Y));
            isDragged = false;
        }
    }

    private void control_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.None; 
    }

    /// <summary>
    /// Prevents Window and any of the controls from being dragged by means 
of the mouse.
    /// </summary>
    /// <param name="message"></param>
    protected override void WndProc(ref Message message)
    {
        int WM_NCLBUTTONDOWN = 0xA1;
        int WM_SYSCOMMAND = 0x112;
        int HTCAPTION = 0x02;
        int SC_MOVE = 0xF010;

        if (message.Msg == WM_SYSCOMMAND && message.WParam.ToInt32() == 
SC_MOVE)
        {
            return;
        }

        if (message.Msg == WM_NCLBUTTONDOWN && message.WParam.ToInt32() == 
HTCAPTION)
        {
            return;
        }

        base.WndProc(ref message);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DraggableControls
{
    public static class ControlDragExtension
    {
        private static Dictionary<Control, bool> 
    controlDraggabilityByControl = new Dictionary<Control, bool>(); // TKey 
is 
control to drag, TValue is a Boolean 
flag used to determine the dragging state.
    private static System.Drawing.Size mouseOffset;

    /// <summary>
    /// Enable/Disable control dragging.
    /// </summary>
    public static void Draggable(this Control control, bool enable)
    {
        if (enable) // Enable control drag feature.
        {
            if (controlDraggabilityByControl.ContainsKey(control))
            {  
                return; // Return if control is already draggable.
            }
            controlDraggabilityByControl.Add(control, false); // 'false' - 
Initial state is 'control not draggable'.

            // Assign required event handlers.
            control.MouseDown += new MouseEventHandler(Control_MouseDown);
            control.MouseUp += new MouseEventHandler(Control_MouseUp);
            control.MouseMove += new MouseEventHandler(Control_MouseMove);
        }
        else // Disable control drag feature.
        {

            if (!controlDraggabilityByControl.ContainsKey(control))
            { 
                return; // Return if control is not draggable.
            }
            // Remove event handlers.
            control.MouseDown -= Control_MouseDown;
            control.MouseUp -= Control_MouseUp;
            control.MouseMove -= Control_MouseMove;
            controlDraggabilityByControl.Remove(control);
        }
    }

    static void Control_MouseDown(object sender, MouseEventArgs e)
    {
        mouseOffset = new System.Drawing.Size(e.Location);
        controlDraggabilityByControl[(Control)sender] = true; // Turn 
control dragging feature on.
    }

    static void Control_MouseUp(object sender, MouseEventArgs e)
    {
        controlDraggabilityByControl[(Control)sender] = false; // Turn 
control dragging feature off.
    }

    static void Control_MouseMove(object sender, MouseEventArgs e)
    {
        if (controlDraggabilityByControl[(Control)sender] == true) // Only 
if dragging is turned on.
        {
            // Calculation of control's new position.
            System.Drawing.Point newLocationOffset = e.Location - 
    mouseOffset;
            ((Control)sender).Left += newLocationOffset.X;
            ((Control)sender).Top += newLocationOffset.Y;
            }
        }
    }
}

即使我有以下陈述:this.AllowDrop = false; , panel1.AllowDrop = false;和 button1.Draggable(false);以及应该禁用拖动的覆盖 void WndProc 方法, button1 始终是可拖动的。

【问题讨论】:

  • 你的按钮应用了重复的逻辑:一个来自ControlDragExtension,一个你自己提供,用重复的事件处理程序覆盖扩展方法。
  • @Jimi 谢谢。我停止使用该类:ControlDragExtension alltogether。

标签: winforms drag-and-drop


【解决方案1】:

我因此更改了事件处理程序:

private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            if (enableDragOperations)
            {
                if (e.Button == MouseButtons.Left)
                {
                    isDragged = true;
                    Point ptStartPosition = senderButton.PointToScreen(new Point(e.X, e.Y));

                    pointOffset = new Point();
                    pointOffset.X = senderButton.Location.X - ptStartPosition.X;
                    pointOffset.Y = senderButton.Location.Y - ptStartPosition.Y;
                }
                else
                {
                    isDragged = false;
                }
            }
        }
    }

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            if (enableDragOperations)
            {
                if (isDragged)
                {
                    Point newPoint = senderButton.PointToScreen(new Point(e.X, e.Y));
                    newPoint.Offset(pointOffset);
                    senderButton.Location = newPoint;
                }
            }
        }
    }

    private void button1_MouseUp(object sender, MouseEventArgs e)
    {
        if (sender is Button)
        {
            Button senderButton = (Button)sender;
            if (enableDragOperations)
            {
                Point newPoint = senderButton.PointToScreen(new Point(e.X, e.Y));
                isDragged = false;
            }
        }
    }

我定义了一个全局字段:bool enableDragOperations 并将其设置为 false。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    相关资源
    最近更新 更多