首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于在运行时移动图片框的DragDrop

问用于在运行时移动图片框的DragDrop
EN

Stack Overflow用户
提问于 2012-11-06 13:42:13
回答 2查看 3.1K关注 0票数 0

我有一个名为pic的PictureBox,放在另一个名为picTrack的PictureBox中。

我的目标是能够让用户在运行时通过拖动来改变pic的位置。

这就是我到目前为止所知道的:

代码语言:javascript
复制
    int x_offset = 0; // any better to do this without having a global variable?
    int y_offset = 0;
    void pic_MouseDown(object sender, MouseEventArgs e)
    {
        PictureBox me = (PictureBox)sender;
        x_offset = me.Left - e.X;
        y_offset = me.Top - e.Y;
    }

    void pic_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            PictureBox me = (PictureBox)sender;
            me.Left = e.X + x_offset; 
            me.Top = e.Y + y_offset;
            picTrack.Invalidate();
        }
    }

这段代码只能在非常基础的级别上工作。我有两个问题:

1.)如果用户不松开鼠标按钮,则不更新picTrack。当pic被移动时,可以看到pic的幽灵图像(就像pic有一条尾巴)。

2.) pic正在“咯咯地笑”(即在其位置周围快速左右摇晃、上下摇晃)。

我应该如何解决这两个问题,并创建一个更流畅的拖放?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-06 14:51:24

在这里,这实际上是有效的,我以前写了相当多的拖拽的东西..它可能并不完美,但这应该会给你提供一些有用的东西。

代码语言:javascript
复制
    Point dragPoint = Point.Empty;
    bool dragging = false;

    private void pic_MouseDown(object sender, MouseEventArgs e)
    {
        dragging = true;
        dragPoint = new Point(e.X, e.Y);
    }

    private void pic_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging)
            pic.Location = new Point(pic.Location.X + e.X - dragPoint.X, pic.Location.Y + e.Y - dragPoint.Y);
    }

    private void pic_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }

看,如果你拖拽一个你自己渲染的本地图片,这是不正确的..但是,由于在移动控件之后要移动该控件,因此新的移动坐标是相对于该控件的。因此,您不需要将dragPoint更新到移动时的最后一个位置。如果你只是移动一个正在渲染OnPaint的形状/图像,你必须在每次移动时更新拖动点。

如果需要,您可以进行一项改进,即仅在用户将光标移动到特定距离D时才开始拖动。例如,如下所示:

代码语言:javascript
复制
    Point dragPoint = Point.Empty;
    bool dragging = false;
    bool mouseDown = false;

    private void pic_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = true;
        dragPoint = new Point(e.X, e.Y);
    }

    private void pic_MouseMove(object sender, MouseEventArgs e)
    {
        int deltaX = e.X - dragPoint.X;
        int deltaY = e.Y - dragPoint.Y;

        if (!dragging && mouseDown && deltaX * deltaX + deltaY * deltaY > 100)
            dragging = true;

        if (dragging)
            pic.Location = new Point(pic.Location.X + deltaX, pic.Location.Y + deltaY);
    }

    private void pic_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
        mouseDown = false;
    }

它检查用户是否已经将鼠标移动了10个像素(sqrt为100)。

如果你不想要一个全局的,你可以尝试实现你自己的行为系统,并创建一段可重用的代码,你可以附加到你想要移动的东西上。如下所示:

代码语言:javascript
复制
public class Behavior<T> where T : class 
{
    public T AssociatedObject
    {
        get;
        private set;
    }

    public Behavior(T associatedObject)
    {
        this.AssociatedObject = associatedObject;
    }

    public virtual void Attach() { }
    public virtual void Detach() { }
}

public class DragBehavior : Behavior<Control>
{
    Point dragPoint = Point.Empty;
    bool dragging = false;
    bool mouseDown = false;

    public DragBehavior(Control c) : base(c)
    {

    }

    public override void Attach()
    {
        AssociatedObject.MouseDown += new MouseEventHandler(control_MouseDown);
        AssociatedObject.MouseMove += new MouseEventHandler(control_MouseMove);
        AssociatedObject.MouseUp += new MouseEventHandler(control_MouseUp);
    }

    private void control_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
        mouseDown = false;
    }

    private void control_MouseMove(object sender, MouseEventArgs e)
    {
        int deltaX = e.X - dragPoint.X;
        int deltaY = e.Y - dragPoint.Y;

        if (mouseDown && deltaX * deltaX + deltaY * deltaY > 100)
            dragging = true;

        if (dragging)
            AssociatedObject.Location = new Point(AssociatedObject.Location.X + deltaX, AssociatedObject.Location.Y + deltaY);
    }

    private void control_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = true;
        dragPoint = new Point(e.X, e.Y);
    }

    public override void Detach()
    {
        AssociatedObject.MouseDown -= new MouseEventHandler(control_MouseDown);
        AssociatedObject.MouseMove -= new MouseEventHandler(control_MouseMove);
        AssociatedObject.MouseUp -= new MouseEventHandler(control_MouseUp);
    }
}

public partial class Form1 : Form
{
    DragBehavior dragger;

    public Form1()
    {
        InitializeComponent();
        DoubleBuffered = true;

        dragger = new DragBehavior(pic);
        dragger.Attach();
    }       
}

也许这比“创建全局变量”(或者更像是在表单中创建成员变量)要好。=)

票数 1
EN

Stack Overflow用户

发布于 2012-11-06 13:56:55

尝尝这个

代码语言:javascript
复制
int x_offset = 0; // any better to do this without having a global variable?
int y_offset = 0;
private void pic_MouseDown(object sender, MouseEventArgs e)
{
   PictureBox me = (PictureBox)sender;
   x_offset = e.X;
   y_offset = e.Y;
}

private void pic_MouseMove(object sender, MouseEventArgs e)
{
  if (e.Button == System.Windows.Forms.MouseButtons.Left)
  {
     PictureBox me = (PictureBox)sender;
     me.Left = e.X + me.Left - x_offset;
     me.Top = e.Y + me.Top - y_offset;
   }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13245083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档