Usercontrol drag & drop on Panel

℡╲_俬逩灬. 提交于 2019-12-13 08:58:22

问题


I'm making a graphical editor, but I am experiencing some problems with the drag & drop over a Panel. The Ellipse doesn't take the exact position where I drop it, and I think it's placed in a UserControl of size 150;150. Here's a link of a short movie to illustrate what I mean: http://gyazo.com/abf5484a31e2d1ce8ebccc49bee9fdb6 In the first part you can see that the Ellipse goes to the wrong position and in the end of the movie when I draw a line it seems that the ellipse has a block around it. How can I solve this issues?

Form1.cs

public partial class Form1 : Form
{
    bool draw = false;
    int x, y, xe, ye;

    public Form1()
    {
        InitializeComponent();

        menuComboBoxShape.ComboBox.DataSource = Enum.GetValues(typeof(Item));
    }

    public enum Item
    {
        Pencil,
        Rectangle, 
        Ellipse,
    }


    private void panel_MouseDown(object sender, MouseEventArgs e)
    {
        draw = true;
        x = e.X;
        y = e.Y;
    }

    private void panel_MouseUp(object sender, MouseEventArgs e)
    {
        draw = false;
        xe = e.X;
        ye = e.Y;

        Item item; 
        Enum.TryParse<Item>(menuComboBoxShape.ComboBox.SelectedValue.ToString(), out item);

        switch (item)
        {

            case Item.Pencil:
                using (Graphics g = panel.CreateGraphics())
                    using (var pen = new Pen(System.Drawing.Color.Black))     //Create the pen used to draw the line (using statement makes sure the pen is disposed)
                    {
                        g.DrawLine(pen,new Point(x, y), new Point(xe, ye));
                    }
                break;
            case Item.Rectangle:
                RectangleShape recShape = new RectangleShape(x, y, xe - x, ye - y);
                panel.Controls.Add(recShape);
                panel.Invalidate();
                break;
            case Item.Ellipse:
                EllipseShapeTest test = new EllipseShapeTest(x, y, xe - x, ye - y);
                panel.Controls.Add(test);
                panel.Invalidate();
                break;
            default:
                break;
        }
    }
}

EllipseShapeTest.cs

class EllipseShapeTest : UserControl
{
    private int x;
    private int y;
    private int width;
    private int height;

    public EllipseShapeTest(int x, int y, int width, int height)
    {
        setY(y);
        setX(x);
        setWidth(width);
        setHeight(height);
    }

    public int getX() { return x;}
    public int getY() { return y; }
    public int getWidth() { return width; }
    public int getHeight() { return height; }
    public void setX(int newx) { x = newx; }
    public void setY(int newy) { y = newy; }
    public void setWidth(int newwidth) { width = newwidth; }
    public void setHeight(int newheight) { height = newheight; }


    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        // Call methods of the System.Drawing.Graphics object.

        // Draw an aqua rectangle in the rectangle represented by the control.
        e.Graphics.DrawEllipse(Pens.Aqua,x,y,width,height);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {

        // Make the cursor the Hand cursor when the mouse moves  
        // over the button.
        Cursor = Cursors.Hand;

        // Call MyBase.OnMouseMove to activate the delegate. 
        base.OnMouseMove(e);

        if (e.Button == MouseButtons.Left)
        {
            this.Location = new Point(e.X, e.Y);
            Invalidate();
        }
     }

回答1:


Here is a Label subclass that is draggable. The same code should work with any control, including your UserControl.

 public DragLabel()
 {
     //..
     MouseDown += DragLabel_MouseDown;
     MouseMove += DragLabel_MouseMove;
 }

 Point mDown { get; set; }

 void DragLabel_MouseDown(object sender, MouseEventArgs e)
 {
      mDown = e.Location;
 }

 void DragLabel_MouseMove(object sender, MouseEventArgs e)
 {
      if (e.Button == MouseButtons.Left)
      {
           Location = new Point(e.X + Left - mDown.X, e.Y + Top - mDown.Y);
      }
 }

If your application needs to make several classes draggable, you could put the fuctionality in a DragController class and register those controls that need it there..

As for your second problem: In the example we see only one control. In this simple case it should do to make the UC's BackColor = Color.Transparent. But once you want to add more such shapes you will hit a wall and, I'm afraid, you will have to give up on such a design. See here for a discussion of the problems and my suggested solution..!

BTW: Using a Control to move around the active shape is fine, but all other shapes will have to be Drawn onto the background. (This makes more sense after you have fully understood the last paragraph ;-)



来源:https://stackoverflow.com/questions/30254957/usercontrol-drag-drop-on-panel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!