【问题标题】:"Click and Drag-Mouse-Over" behavior for Objects in a Panel面板中对象的“单击并拖动鼠标悬停”行为
【发布时间】:2012-07-26 16:08:44
【问题描述】:

我会尽量保持这个通用性以供将来参考。

假设我们的表单有一个正方形网格(我们将分别称为“点”的矩形形状。)由于此网格的大小在表单加载之前可能会发生变化,因此我们在面板中创建了所有点当我们第一次加载我们的表单并可以使用...

foreach (Squares point in mySquares)

...当我们想要改变他们的行为或外表时。现在,我们已经开发了代码来在用户单击左或右时更改每个点的颜色。它看起来像:

private void panelGrid_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
    {
        foreach (Squares point in mySquares)
        {
            if (point.Rectangle.Contains(e.Location))     // determine which point to use
            {
                if (e.Button == MouseButtons.Left)
                {
                    Pencil(point);        // left-click to fill color
                }
                else
                {
                    Erase(point);       // right-click to erase color
                }
            }
        }
    panelGrid.Invalidate();            // refreshes grid
    }
}

这就像一个魅力。但是假设我们需要更改此代码:现在我们还希望在按住鼠标按钮并将光标移动到新点时更改颜色。 (有点像 MS-Paint:将铅笔工具拖到多个像素上会依次填充每个像素。)

让我感到困惑的是正确实施此行为的正确方法。据我了解,我希望 Pencil/Eraser 方法在以下情况下调用:

A.)鼠标进入一个“点”并且一个按钮已经被按下。

B.) 鼠标按钮被按下。 (见上面的代码)

这对我来说比较棘手是确定如何最好地实施新检查,以及如何在网格中的各个点上执行它们 - 或者即使这是必要的。有什么建议吗?

【问题讨论】:

    标签: c# winforms mouseevent panel


    【解决方案1】:

    听起来您希望 MouseDown 和 MouseMove 事件做同样的事情:

    private void MouseStuff(MouseEventArgs e) {
      if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
      {
        foreach (Squares point in mySquares) {
          if (point.Square.Contains(e.Location)) {
            if (e.Button == MouseButtons.Left) {
              Pencil(point);
            } else {
               Erase(point);
            }
          }
        }
        panelGrid.Invalidate();
      }
    }
    

    然后尝试从两个事件中调用它:

    private void panelGrid_MouseDown(object sender, MouseEventArgs e) {
      MouseStuff(e);
    }
    
    private void panelGrid_MouseMove(object sender, MouseEventArgs e) {
      MouseStuff(e);
    }
    

    考虑使用双缓冲面板来减少控件的抖动,因为在 MouseMove 事件上使面板无效可能会非常密集:

    public class BufferedPanel : Panel {
      public BufferedPanel() {
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
      }
    }
    

    【讨论】:

    • 我喜欢解决方案如此简单,但我总是讨厌自己错过它。完美运行! - 另外,特别感谢您提供的 BufferedPanel 提示,它解决了我遇到的多个其他问题。
    • @Doc 没问题,很高兴为您提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多