OnPaint,Invalidate,Clipping和Regions的最佳实践

时间:2011-09-21 22:41:38

标签: c# clipping region invalidation onpaint

我有一个用户控件,其中包含许多自绘的完全自定义绘制图形(从OnPaint调用),背景为大位图。我内置了缩放和平移功能,并且在画布上绘制的对象的所有坐标都在位图坐标中。

因此,如果我的用户控件宽度为1000像素,则位图宽度为1500像素,并且我以200%缩放进行缩放,然后在任何给定时间我只会看到位图宽度的1/3。并且,如果您滚动到最左侧,则在位图上从点100,100开始具有矩形的对象将出现在屏幕上的点200,200处。

基本上我需要做的是创建一种有效的方式来重绘仅需要重绘的内容。例如,如果我移动一个对象,我可以将该对象的旧剪辑矩形添加到一个区域,并将该对象的新剪辑矩形与该区域合并,然后调用Invalidate(region)来重绘这两个区域。 / p>

但是这样做意味着我必须不断地将对象位图坐标转换为屏幕坐标,然后再将它们提供给Invalidate。我必须总是假设PaintEventArgs中的ClipRectangle处于屏幕坐标中,以便其他窗口无效时使用。

有没有办法可以使用Region.Transform和Region.Translate功能,这样我就不需要从位图转换为屏幕坐标?在某种程度上它不会干扰在屏幕坐标中接收PaintEventArgs?我应该使用多个地区还是有更好的方法来做这一切?

我现在正在做的示例代码:

invalidateRegion.Union(BitmapToScreenRect(SelectedItem.ClipRectangle));

SelectedItem.UpdateEndPoint(endPoint);

invalidateRegion.Union(BitmapToScreenRect(SelectedItem.ClipRectangle));

this.Invalidate(invalidateRegion);

在OnPaint()......

protected override void OnPaint(PaintEventArgs e)
{
    invalidateRegion.Union(e.ClipRectangle);

    e.Graphics.SetClip(invalidateRegion, CombineMode.Union);
    e.Graphics.Clear(SystemColors.AppWorkspace);

    e.Graphics.TranslateTransform(AutoScrollPosition.X + CanvasBounds.X, AutoScrollPosition.Y + CanvasBounds.Y);

    DrawCanvas(e.Graphics, _ratio);

    e.Graphics.ResetTransform();

    e.Graphics.ResetClip();

    invalidateRegion.MakeEmpty();
}

0 个答案:

没有答案