【问题标题】:Unusual dragging issue不寻常的拖动问题
【发布时间】:2012-01-24 15:46:05
【问题描述】:

我有一个图片框,用户可以向上或向下拖动它。

所讨论的程序是一个复杂的钢琴谱表编辑器,因此在谱表上实现音符移动的唯一方法是使用多个 if 语句和修改坐标。

问题是用户无法将 PictureBox 组件向下移动,但是当对象被向上拖动时,什么也没有发生。该类继承自 PictureBox。

我想强调的是,PictureBox 在向下拖动时可以工作,但在向上拖动时不会移动。拖动是间隔进行的,即 PictureBox 只能放置在某些地方(因此需要特定的坐标)。

【问题讨论】:

  • (无关:我会发现您的Top 支票非常如果它们在number-line order 中更容易阅读 - 您可能同意也可能不同意)
  • sn-p 不足以诊断它。典型的问题是移动控件也会改变鼠标的相对位置。
  • 奇怪的是,当我向下移动鼠标时它可以工作——实际上它工作得很好。但是当我向上移动鼠标时,它没有。我在这两种情况下使用几乎相同的代码。
  • 您应该发布更多代码。例如,您在哪里附加 MouseMove 处理程序?您发布的代码仅在释放按钮时将其分离。你确定你没有在OnDrag 中更改currentY(顺便说一句,这不是MouseMove 处理程序的好名字)?此外,尚不清楚此代码的位置。在你的PictureBox-派生类里面?为什么你的处理程序是公开的?通过这种方式很难找到问题。有比使用多个 if 语句更好的方法来解决这个问题,但是当它的工作原理不完全清楚时,很难提出解决方案。
  • @Groo 我编辑了上面的代码以显示处理程序的附加。 currentY 在“OnDrag”中没有改变,这段代码位于我的 PictureBox 派生类中。

标签: c# winforms drag-and-drop picturebox


【解决方案1】:

您当前的解决方案有时可能会起作用,但是当您尝试拖动控件并将其捕捉回您在if 语句中指定的坐标时,可能会经常调用该事件。

建议的解决方案:

我建议您在包含您要拖动的控件的表单或父级中使用MouseMove 事件。这些值也应该是可配置的,而不是硬编码的。 代码只会稍微改变(比较当前鼠标坐标而不是控件的LeftTop 属性),它应该可以正常工作。

更新:

我已经更正了您的代码,因此它现在可以让您将控件放在三个位置之一(y 等于 138148 158)。我只是稍微改了一下,不需要你改很多代码,但我强烈建议你使用描述的第一种方法:)。

    int currentY;
    bool isDragging = false;

    private void OnDrag(object sender, MouseEventArgs e)
    {
        if (isDragging)
        {
            //calculate Y position relative to parent
            int parentY = this.Top + e.Y;

            if (parentY < currentY)
            {
                if (parentY > 158 && parentY >= 148)
                {
                    if (this.Top != 148)
                    {
                        currentY += (this.Top - 148);
                        this.Top = 148;
                    }
                }
                else if (parentY < 148 /*&& parentY >= 138*/)
                {
                    if (this.Top != 138)
                    {
                        currentY += (this.Top - 138);
                        this.Top = 138;
                    }
                }

                //And so on

            }
            else if (parentY > currentY)
            {
                if (/*parentY <= 158 &&*/ parentY >= 148)
                {
                        currentY += (this.Top - 158);
                        this.Top = 158;
                }
                else if (parentY < 148 && parentY >= 138)
                {
                        currentY += (this.Top - 148);
                        this.Top = 148;
                }

                //And so on

            }
        }
    }

    public void MusicNote_MouseDown(object sender, MouseEventArgs e)
    {
        currentY = this.Top + e.Y;

        this.Capture = true;

        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            isDragging = true;
        }

        this.MouseMove += new MouseEventHandler(OnDrag);
    }

    public void MusicNote_MouseUp(object sender, MouseEventArgs e)
    {
        isDragging = false;

        this.Capture = false;

        this.MouseMove -= new MouseEventHandler(OnDrag);
    }

但是,之前的解决方案可能会更符合您的要求。

【讨论】:

  • 感谢您的回复!您能否详细说明“快速建议的解决方案”?不确定我是否完全理解您的意思。
  • 试过了,还是有这个问题。
  • 感谢卢卡斯的帮助,不幸的是这也不起作用。这可能归结为 PictureBox 类的缺陷。我仍然会为你的努力标记你的答案 - 也许它会在未来帮助其他人。非常感谢!
  • 我编写了一个测试应用程序,在其中使用这段代码,它就可以工作了。尝试将控件放在 y 最初等于 148 的位置中。感谢您标记答案:),但我仍然想帮助您:)。
  • 谢谢卢卡斯,我又试了一次,但由于某种原因,向下拖动时拖动有效,但向上拖动时无效。当我尝试向上拖动时,第一级之后没有任何反应。有什么想法吗?
猜你喜欢
  • 2012-01-25
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
相关资源
最近更新 更多