用户控件拖放放在面板上 [英] Usercontrol drag & drop on Panel

查看:76
本文介绍了用户控件拖放放在面板上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



Form1.cs

  public局部类Form1:表格
{
bool draw = false;
int x,y,xe,ye;

公共Form1()
{
InitializeComponent();

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

公共枚举项
{
铅笔,
矩形,
椭圆形,
}


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;

项目;
Enum.TryParse< Item>(menuComboBoxShape.ComboBox.SelectedValue.ToString(),输出项);

开关(项目)
{

case Item.Pencil:
using(Graphics g = panel.CreateGraphics())
using (var pen = new Pen(System.Drawing.Color.Black))//创建用于绘制线条的笔(使用语句确保已放置笔)
{
g.DrawLine(pen ,new Point(x,y),new Point(xe,ye));
}
休息;
case Item.Rectangle:
RectangleShape recShape = new RectangleShape(x,y,xe-x,ye-y);
panel.Controls.Add(recShape);
panel.Invalidate();
休息时间;
case Item.Ellipse:
EllipseShapeTest test = new EllipseShapeTest(x,y,xe-x,ye-y);
panel.Controls.Add(test);
panel.Invalidate();
休息时间;
默认值:
休息时间;
}
}
}

EllipseShapeTest.cs

  class EllipseShapeTest:UserControl 
{
private int x;
private iny y;
private int width;
私人int高度;

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(){返回宽度; }
public int getHeight(){返回高度; }
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; }


受保护的覆盖无效OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//调用System.Drawing.Graphics对象的方法。

//在控件表示的矩形中绘制一个浅绿色矩形。
e.Graphics.DrawEllipse(Pens.Aqua,x,y,width,height);
}

受保护的覆盖无效OnMouseMove(MouseEventArgs e)
{

//将光标移至
时将其作为手形光标//在按钮上。
Cursor = Cursors.Hand;

//调用MyBase.OnMouseMove激活委托。
base.OnMouseMove(e);

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


解决方案

此处是可拖动的 Label 子类。相同的代码应适用于任何控件,包括您的 UserControl

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

Point mDown {get;组; }

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

void DragLabel_MouseMove(对象发送者,MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
位置=新点(eX +左-mDown.X,eY +顶-mDown.Y);
}
}

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



第二点问题:在该示例中,我们仅看到一个控件。在这种简单情况下,应该使UC的 BackColor = Color.Transparent 。但是一旦您想添加更多这样的形状,就会撞墙,而且恐怕您将不得不放弃设计。请参阅此处以了解有关问题和建议的解决方案的信息。 / p>

BTW:使用控件活动周围移动 >形状还可以,但是所有其他形状都必须绘制到背景上。 (在您完全理解最后一段之后,这才更有意义;-)


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

解决方案

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

这篇关于用户控件拖放放在面板上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆