Member 14015063 Ответов: 3

C# winforms drag and drop


Hi, trying to implement drag and drop
I have custom ToolBox class that simply iherits FlowLayoutPanel, and some picture boxes within. When user clicks on any of these picture boxes, it got copied and added to form's controls just on top of original. Then when user moves mouse around with left button pressed, that picture box should move along, but it don't. It works only if you release mouse button and then click again and move.


Что я уже пробовал:

//want to mentioned that that's not the full code, only what is related to the question
 public partial class FigureToolBox : FlowLayoutPanel
 {

        public delegate void FigureSelected(PictureBox figurePicture,Point location);

        public event FigureSelected OnFigureSelect;
       
      //on mouse down of each picture box
      public void Figure_mouse_down(object c, MouseEventArgs e)
        {
            PictureBox pictureBox = c as PictureBox;

            PictureBox clonedPicture = new PictureBox();
            clonedPicture.SizeMode = PictureBoxSizeMode.AutoSize;
            clonedPicture.Image = pictureBox.Image;
            
            OnFigureSelect(clonedPicture, e.Location);

        }

     //some code
}
public partial class GameForm : Form
{
   Point point = new Point(); //start point of moving
   PictureBox draggedFig;


   public GameForm()
   {
     InitializeComponent();
     figureToolBox1.OnFigureSelect += FigureSelected;
   }

   private void FigureSelected(PictureBox box, Point location)
   {
            draggedFig = box;
            //just calculating  location of picture box in form's coords
            Point point = PointToClient(Cursor.Position);
            box.Left = (point.X- location.X);
            box.Top = (point.Y- location.Y);

            this.point = location;
            
            this.Controls.Add(draggedFig);
            draggedFig.BringToFront();

            draggedFig.MouseMove += DraggedFig_Move;
            draggedFig.Focus(); //thought it will help, but it won't
     }

    private void DraggedFig_Move(object sender, MouseEventArgs e){

            if (e.Button == MouseButtons.Left)
            {
                draggedFig.Left += e.X - point.X;
                draggedFig.Top += e.Y - point.Y;
            }
     }
}

Member 14015063

Наконец-то понял. Просто нужно было отключить toolbox перед запуском OnFigureSelect:
...
этот.Включен = ложь;
OnFigureSelect(clonedPicture, e.Location);

А затем включите его обратно, когда отпустите кнопку мыши.

3 Ответов

Рейтинг:
1

BillWoodruff

Во-первых, имейте в виду, что вы не используете средство перетаскивания WinForms, которое имеет некоторые сложные функции для предоставления обратной связи во время перетаскивания и т. д.

Посмотрите, есть ли у вас какие-то идеи из этого примера, который, как и ваш, использует простой метод

using System;
using System.Windows.Forms;

namespace YourNameSpace
{
    public partial class ToolBoxPanel : UserControl
    {
        public ToolBoxPanel()
        {
            InitializeComponent();
        }


        private void ToolBoxPanel_Load(object sender, EventArgs e)
        {
            parent = this.Parent as Form;
        }

        private PictureBox currentPB;

        private bool IsMouseUp = true;

        private CheckBox cb;

        private int cbCount = 0;

        private Form parent;

        // all PicturewBoxes in the UserControl use this Handler
        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            currentPB = sender as PictureBox;

            switch (currentPB.Name)
            {
                case "pictureBox1":

                    cb = new CheckBox();

                    parent.Controls.Add(cb);
                    cb.Text = "CheckBox " + cbCount++;
                    cb.Show();
                    cb.BringToFront();

                    break;
            }

            IsMouseUp = false;
        }

        // all PicturewBoxes in the UserControl use this Handler
        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            IsMouseUp = true;

            // cancel the drop if it's not over the Form ?
            if(this.DisplayRectangle.Contains
              (this.PointToClient
                (currentPB.PointToScreen(e.Location))))
            {
                parent.Controls.Remove(cb);
                cb.Dispose();
            }
        }

        // all PicturewBoxes in the UserControl use this Handler
        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsMouseUp) return;

            // map the mouse location to the Parent Form
            cb.Location = parent.PointToClient(this.PointToScreen(e.Location));
        }
    }
}
Примечание: перемещенный элемент управления в этом примере не является перемещаемым после его размещения в родительской форме.


Рейтинг:
0

Gerry Schmitz

Посмотрите, где находится "фокус". Если вы можете установить фокус на новый PictureBox (что, вероятно, и делает второй щелчок), это может сработать.


Member 14015063

Ну, я пытался, но ничего не вышло. А вот и строчка: драггедфиг.Сосредоточить();
Или есть другой способ сосредоточиться на контроле?

Gerry Schmitz

Вам нужно "проследить" все события. Если установка его в одной точке не работает, он может в другой. У вас есть конкретный сценарий, который вам нужно понять с точки зрения того, что происходит, какое поведение "пропустить" и т. д. Не существует "одного размера для всех". Это вопрос концентрации. Справиться с этим.