在 C# 中的面板上拖放时移动控件

Posted

技术标签:

【中文标题】在 C# 中的面板上拖放时移动控件【英文标题】:Move controls when Drag and drop on panel in C# 【发布时间】:2011-01-27 04:46:59 【问题描述】:

我想拖动面板上的控件,拖动时我想移动控件并将其位置放到面板上。我已经尝试过 mouseUp、mouseDown、MouseMove 控制事件。但这不是我想要的。我想在面板上触发 DragDrop 事件并移动控件。我可以这样做吗?如果你能给我一个想法,那就太好了。以下是我的代码的一部分。请纠正我。非常感谢。

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;

namespace DragnDrop

    public partial class Form1 : Form
    

        public Form1()
        
            InitializeComponent();
        
        Control mycontrol;
        int x, y;
        //Form1 f = new Form1();
        private void Form1_Load(object sender, EventArgs e)
        

            foreach (Control c in this.panel1.Controls)
            
                c.MouseMove += new MouseEventHandler(lblDragger_MouseMove);
                c.MouseUp += new MouseEventHandler(lblDragger_MouseUp);
                c.MouseDown += new MouseEventHandler(pictureBox1_MouseDown);
                c.MouseDoubleClick += new MouseEventHandler(pictureBox1_MouseDown);
            
            panel2.AllowDrop = true;
            foreach (Control c in this.panel2.Controls)
            
                c.MouseDown += new MouseEventHandler(pictureBox1_MouseDown);
            
            panel2.DragOver += new DragEventHandler(panel2_DragOver);
            panel2.DragDrop += new DragEventHandler(panel2_DragDrop);  
        

        bool isDragging ;
        int  clickOffsetX ;
        int  clickOffsetY ;

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        
            //  this.Cursor = Cursors.SizeAll;
            //pictureBox1 = (PictureBox)sender;
            Control c = sender as Control;

            //DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
            // validation = true;
            isDragging = true;
            clickOffsetX = e.X;
            clickOffsetY = e.Y;
            //  c.DoDragDrop(c, DragDropEffects.Move);  
        

        private void lblDragger_MouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e)
        
            isDragging = false;
        

        private void panel2_DragEnter(object sender, DragEventArgs e)
        
            if (e.Data.GetDataPresent(typeof(Bitmap)))
            
                e.Effect = DragDropEffects.Copy;
            
            else
            
                e.Effect = DragDropEffects.None;
            
        

        private void panel2_DragOver(object sender, DragEventArgs e)
        
            e.Effect = DragDropEffects.Move;  
        

        private void panel2_DragDrop(object sender, DragEventArgs e)
        
            Control c = e.Data.GetData(e.Data.GetFormats()[0]) as Control;
            mycontrol = c;
            if (c != null)
            
                c.Location = this.panel2.PointToClient(new Point(e.X, e.Y));
                this.panel2.Controls.Add(c);
              
        

        private void lblDragger_MouseMove(System.Object sender,
          System.Windows.Forms.MouseEventArgs e)
        
            Control c = sender as Control;
            // bool isDragging = true;
            if (isDragging == true)
            
                c.Left = e.X + c.Left - clickOffsetX;
                c.Top = e.Y + c.Top - clickOffsetY;
            
        

        private void panel1_MouseLeave(object sender, EventArgs e)
        
            Control c = sender as Control;

            c.DoDragDrop(c, DragDropEffects.Move); 
        
    

【问题讨论】:

【参考方案1】:

如果您的控件已经在面板上,并且您只是在同一个面板中移动它,那么使用鼠标事件可能是最简单的方法。我的理解是拖放更多的是关于在控件甚至应用程序之间传递数据。例如,如果您尝试允许控件在面板之间传输,拖放将是一个很好的选择。


如果你想两者都做,那么这里有一个可能的想法:

    使用鼠标事件在同一面板内执行移动拖动。

    1234563控制权可能会离开。

    处理目标面板上的 DragDrop 并将控件放置在拖放的鼠标位置。

这结合了拖动控件的直观感觉,同时还提供了一种将“越过”面板拖动到新表面的方法。

【讨论】:

感谢您的回复。是的,我想在面板中移动控件,也想将控件从一个面板拖放到另一个面板。所以我想同时实现。我该怎么做? 谢谢。这里你说要处理 c.DoDragDrop(c, DragDropEffects.Move);在第一个面板的 mouseLeave 事件中?我正确吗?但它只在同一面板内移动控件。 :( 您需要执行以下操作(通常在 Google 上可以找到很多 DragDrop 的示例): - 当鼠标离开时调用 DoDragDrop,使用您一直在里面“拖动”的控件面板 - 确保您的目标面板已将 AllowDrop 设置为 true - 处理目标面板的 DragEnter 和 DragDrop 事件以提供上下文并处理实际的放置操作。 但是当我在鼠标离开时调用 DoDragDrop 时,不能将控件拖动到其他面板。我已经处理了拖放,第二个面板中的 DragEnter 事件。但它们只能在同一个面板上移动。错过了什么? 我也添加了一部分代码。希望您能帮助我。谢谢【参考方案2】:

您需要使用鼠标向上和鼠标向下事件来切换拖动状态。当您按下鼠标时,您开始拖动。您记录鼠标在控件中的相对位置以及控件在面板中的相对位置。然后,您跟随鼠标移动并重新定位控件的顶部和左侧相对于鼠标在控件中的原始位置。

【讨论】:

以上是关于在 C# 中的面板上拖放时移动控件的主要内容,如果未能解决你的问题,请参考以下文章

新添加的行不能拖放到 extjs 网格面板中

ChinaCock界面控件介绍-CCNavigateTitle

如何在 C# 中为我的控件添加移动效果?

我们如何获得相对于窗口形式的位置?

C# 在面板周围拖动控件

Java swing拖放记事本[关闭]