0

我正在制作工具来选择图像的一部分。我有 PictrureBox,制作方法很简单:

void StartPanel(object sender, MouseEventArgs args)
{
    xStart = args.X;
    yStart = args.Y;
    panelStarted = true;
    pan.Location = new Point(xStart, yStart);
}
void FinishPanel(object sender, MouseEventArgs args)
{
    xFinish = args.X;
    yFinish = args.Y;
    panelStarted = false;
}

void UpdatePanel(object sender, MouseEventArgs args)
{
    if (panelStarted)
    {
        int x = args.X;
        int y = args.Y;

        int newxstart = xStart;
        int newystart = yStart;
        int neww = 0;
        int newh = 0;

        if (x >= xStart)
            neww = x - xStart;
        else
        {
            neww = xStart - x;
            newxstart = x;
        }
        if (y >= yStart)
            newh = y - yStart;
        else
        {
            newh = yStart - y;
            newystart = y;
        }

        pan.Size = new Size(neww, newh);
        pan.Location = new Point(newxstart, newystart);
    }
}

当我左右移动鼠标时,绝对没问题。但是当我将它向左或向上移动时,我可以看到我所在区域的闪烁。所以我明白了,这是因为当我向左或向上移动鼠标时,我的面板被重绘,因为 Panel.Location 改变了,当我向右和向下移动鼠标时,位置没有改变,只有大小改变,所以它不会重绘,只是将一些像素添加到面板中。什么是标准解决方案?

4

2 回答 2

0

由于您在调整面板大小时描述了绘图问题,因此最简单的解决方法可能是将您正在使用的面板替换为双缓冲面板,并且在调整事件大小时将失效:

public class BufferedPanel : Panel {
  public BufferedPanel() {
    this.DoubleBuffered = true;
    this.ResizeRedraw = true;
  }
}
于 2012-07-11T14:14:14.763 回答
0

尝试查看您要执行的操作并不容易,但我猜您正在使用面板作为可拖动控件来拖动图片框表面以捕获下面的图像部分(如镜头) - 是吗?

如果是这样,那么这不是最好的方法。最好在图片框表面上绘制一个矩形并“拖动”它 - 这很简单,只需使用鼠标事件设置左上角并使用 onpaint 在图像上绘制未填充的矩形。准备好后使用您希望的任何事件捕获图像也很简单,然后将具有相同位置的图像复制到新位图。

将一个控件置于另一个控件上通常会导致闪烁 - 即使使用双缓冲也是如此。它还需要更多的代码。

于 2012-07-11T14:40:40.350 回答