1

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

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

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.)鼠标按钮被按下。(见上面的代码)

这对我来说变得棘手的是确定如何最好地实施新检查,以及如何在网格中的各个点上执行它们——或者即使这是必要的。有小费吗?

4

1 回答 1

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;
  }
}
于 2012-07-26T16:13:49.783 回答