【问题标题】:C# drag controls around a panelC# 在面板周围拖动控件
【发布时间】:2013-08-22 03:04:26
【问题描述】:

我正在开发一个允许用户在同一个面板中拖动对象的系统,我经过一些研究发现我应该使用鼠标事件,如 mouse_up、mouse_down 和 mouse_move。

该程序将生成 3 个图片框并允许用户在面板内的每个图片框周围拖动,但我编写的程序无法完美运行,因为当我拖动图片框时,图片框会移动,但不是根据我的鼠标光标位置,它在其他地方,此外,在拖动时,面板中有图片框阴影,我尝试过那些 update()、refresh() 和 invalidate(),但它似乎对我没有用。以下是我的代码,感谢您的帮助

public partial class Form1 : Form
{

    List<PictureBox> pictureBoxList = new List<PictureBox>();
    private bool isDragging = false;

    public Form1()
    {
        InitializeComponent();

        for (int i = 0; i < 3; i++)
        {
            PictureBox picture = new PictureBox
            {
                Name = "pictureBox" + i,
                Size = new Size(20, 20),
                Location = new Point(i * 40, i * 40),
                BorderStyle = BorderStyle.FixedSingle,
                SizeMode = PictureBoxSizeMode.Zoom,
                ImageLocation = "A.jpg"
            };
            pictureBoxList.Add(picture);


            foreach (PictureBox p in pictureBoxList)
            {
                p.MouseDown += new MouseEventHandler(c_MouseDown);
                p.MouseMove += new MouseEventHandler(c_MouseMove);
                p.MouseUp += new MouseEventHandler(c_MouseUp);
                pnlDisplayImage.Controls.Add(p);
                pnlDisplayImage.Refresh();
            }
        }
    }


    void c_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;
    }

    void c_MouseMove(object sender, MouseEventArgs e)
    {

        if (isDragging == true) {
            Control c = sender as Control;
            for (int i = 0; i < pictureBoxList.Count(); i++)
            {
                if (c.Equals(pictureBoxList[i]))
                {
                    pictureBoxList[i].Location = new Point(e.X, e.Y);
                }
            }
        }
    }

    void c_MouseUp(object sender, MouseEventArgs e)
    {
        PictureBox c = sender as PictureBox;
        isDragging = false;
        for (int i = 0; i < pictureBoxList.Count(); i++) { 
            if (c.Equals(pictureBoxList[i])){
                pictureBoxList[i].Location = new Point(e.X, e.Y);
            }
        }
    }

    private void pnlDisplayImage_Paint(object sender, PaintEventArgs e)
    {
        foreach (PictureBox p in pictureBoxList)
        {
            pnlDisplayImage.Controls.Add(p);
        }
    }

}

【问题讨论】:

    标签: c# winforms mouseevent draggable


    【解决方案1】:

    最后我找到了导致我的程序没有按预期运行的问题。主要问题是我不小心将foreach循环放在了我用来创建pictureBox的for循环中,这个问题导致pictureBox在运行时出现一些阴影效果,因为相同的pictureBox很少。此外,我更改了一些代码,现在它按我的预期运行。以下是我想要回答的代码。

    public partial class Form1 : Form
    {
    
        List<PictureBox> pictureBoxList = new List<PictureBox>();
        private bool isDragging = false;
        Point move;
    
        public Form1()
        {
            InitializeComponent();
    
            for (int i = 0; i < 3; i++)
            {
                PictureBox picture = new PictureBox
                {
                    Name = "pictureBox" + i,
                    Size = new Size(20, 20),
                    Location = new Point(i * 40, i * 40),
                    BorderStyle = BorderStyle.FixedSingle,
                    SizeMode = PictureBoxSizeMode.Zoom,
                    ImageLocation = "A.jpg"
                };
                pictureBoxList.Add(picture);
            }
    
            foreach (PictureBox p in pictureBoxList)
            {
                    p.MouseDown += new MouseEventHandler(c_MouseDown);
                    p.MouseMove += new MouseEventHandler(c_MouseMove);
                    p.MouseUp += new MouseEventHandler(c_MouseUp);
                    pnlDisplayImage.Controls.Add(p);
                    pnlDisplayImage.Refresh();
             }
    
        }
    
        void c_MouseDown(object sender, MouseEventArgs e)
        {
            Control c = sender as Control;
            isDragging = true;
            move = e.Location;
        }
    
        void c_MouseMove(object sender, MouseEventArgs e)
        {
    
            if (isDragging == true) {
                Control c = sender as Control;
                for (int i = 0; i < pictureBoxList.Count(); i++)
                {
                    if (c.Equals(pictureBoxList[i]))
                    {
                        pictureBoxList[i].Left += e.X - move.X;
                        pictureBoxList[i].Top += e.Y - move.Y;
                    }
                }
            }
        }
    
        void c_MouseUp(object sender, MouseEventArgs e)
        {
            isDragging = false;
        }
    }
    

    【讨论】:

      【解决方案2】:

      尝试类似(它是带有覆盖的自定义控件,但应该很容易转换为事件):

          private bool _isMoved = false;  // true if move mode on
          private Point _pointMove = new Point(0);    // for moving
      
          protected override void OnMouseDown(MouseEventArgs e)
          {
              // if left button pressed
              if(e.Button == MouseButtons.Left) 
              {
                  _pointMove.X = e.X;
                  _pointMove.Y = e.Y;
                  _isMoved = true;
                  Cursor = Cursors.SizeAll;
                  Capture = true;
              }
              base.OnMouseDown (e);
          }
      
          protected override void OnMouseUp(MouseEventArgs e)
          {
              // if move mode on
              if(_isMoved) 
              {
                  _isMoved = false;
                  Cursor = Cursors.Default;
                  Capture = false;
              }
              base.OnMouseUp (e);
          }
      
          protected override void OnMouseMove(MouseEventArgs e)
          {
              // if move mode on
              if (_isMoved)
              {
                  Left += e.X - _pointMove.X;
                  Top += e.Y - _pointMove.Y;
              }
              base.OnMouseMove (e);
          }
      

      【讨论】:

      • 嗨 Sinatr,感谢您的回答,我尝试将您给定的代码转换为我的案例,它给了我相同的结果,只是鼠标光标改变了。我在想是不是我的 pnlDisplayImage_Paint 事件导致了问题
      猜你喜欢
      • 2011-01-27
      • 1970-01-01
      • 2012-09-29
      • 2018-10-06
      • 2018-02-22
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多