【问题标题】:Usercontrol drag & drop on Panel面板上的用户控件拖放
【发布时间】:2015-05-15 08:30:56
【问题描述】:

我正在制作一个图形编辑器,但在 Panel 上拖放时遇到了一些问题。 Ellipse 没有采用我放置它的确切位置,我认为它放置在大小为 150;150 的 UserControl 中。这是一个短片的链接来说明我的意思:http://gyazo.com/abf5484a31e2d1ce8ebccc49bee9fdb6 在第一部分中,您可以看到椭圆的位置错误,而在电影的结尾,当我画一条线时,椭圆似乎有一个挡住它。我该如何解决这个问题?

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();
        }
     }

【问题讨论】:

  • this.Location 相对于 UC 的父级,但 e.Location 相对于 UC 表面。通常最好跟踪与 mouseDown 点之间的差异。
  • 在这种情况下我该怎么做?而且 UC 总是 150 x 150,这不会导致定位问题吗?
  • 大小无所谓;但是由于您可以在任何位置“抓住”UC,因此您需要使用该位置来跟踪移动的距离。请参阅我的答案以获取一个非常简单的示例(4 行),并讨论将控件用作图形形状的限制..!

标签: c# winforms user-controls draw drag


【解决方案1】:

这是一个可拖动的Label 子类。相同的代码应该适用于任何控件,包括您的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);
      }
 }

如果您的应用程序需要使多个类可拖动,您可以将功能放在 DragController 类中并在那里注册那些需要它的控件..

至于您的第二个问题:在示例中,我们只看到 one 控件。在这个简单的例子中,它应该做 UC 的BackColor = Color.Transparent。但是一旦你想添加更多这样的形状,你会碰壁,恐怕你将不得不放弃这样的一个设计。请参阅here 讨论问题和我建议的解决方案..!

顺便说一句:使用Control活动 形状周围移动 很好,但所有其他形状都必须是Drawn 到背景上。 (在您完全理解了最后一段之后,这更有意义;-)

【讨论】:

  • 现在可以拖动了,谢谢。您说 UC 的大小无关紧要,但是如果绘制大于 150 x 150 的椭圆,则仅绘制一部分。我不太明白你答案的最后两行。
  • 当然,UC 需要与它应显示的形状一样大。一旦你碰壁并研究了链接的帖子,你就会理解这些行,相信我。如果没有,请回来,但我宁愿不再把它全部写下来。..
猜你喜欢
  • 1970-01-01
  • 2011-01-27
  • 2011-07-18
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多