用户控件拖动&放在面板上

Usercontrol drag amp; drop on Panel(用户控件拖动amp;放在面板上)
本文介绍了用户控件拖动&放在面板上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

推荐答案

这是一个可拖动的 Label 子类.相同的代码应该适用于任何控件,包括您的 UserControl.

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

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

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..

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

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..!

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

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

这篇关于用户控件拖动&amp;放在面板上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)