同时在两个窗口中的两个控件上同时绘制
在我的应用程序中,有2个窗口,都包含一个picturebox。第一个(PB1)允许互动,并且可以通过点击和鼠标事件更改图像。这些事件称为pb1.invalidate();效果很好。
我也希望第二个Picturebox(PB2)重新绘制,因此我从PB1的油漆事件中调用PB2.Invalidate()。 [仅在上下文中,第二个图像框显示几乎相同的图像,但在更大的规模上,将来将遗漏图纸的某些部分,因此我在两个油漆事件中使用相同的方法,这些方法决定要绘制什么,什么不绘制)
它有效,但它是“ Laggy”的,我希望它与第一个Picturebox上的油漆一样光滑。我将油漆事件减少到用于测试目的的网格中。
- 两个窗户都是双重缓冲的。
- 我尝试用Skiasharp的SkglControls替换图片框(该skiasharp的性能应该更好)。示例代码仍然使用Skiaevents,因此如果两个控件都出现问题,请不要混淆。
- 我尝试使用.update()或.refresh()而不是.invalidate(),但我想它要处理的很大,应用程序只是
崩溃
public void Update(SKPaintGLSurfaceEventArgs e, bool bigscreen)
{
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.Beige);
//Zoom to specified area
SKMatrix matrix = SKMatrix.Identity;
if (!bigscreen)
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(canvasSize / (float)zoomArea.Width, canvasSize / (float)zoomArea.Height));
}
else
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(bigCanvasSize / (float)zoomArea.Width, bigCanvasSize / (float)zoomArea.Height));
}
matrix = matrix.PreConcat(SKMatrix.CreateTranslation(-zoomArea.X, -zoomArea.Y));
canvas.SetMatrix(matrix);
DrawGrid(canvas);
}
。方法
private void DrawGrid(SKCanvas canvas)
{
using (SKPaint paint = new SKPaint() { IsAntialias = true,Color=SKColors.LightGray,StrokeWidth = 1})
{
canvas.DrawLine(0, 0, 0, gridCanvas.Height, paint); //Size gridCanvas is always the same at the moment and defines the space where the grid is drawn
canvas.DrawLine(0, 0, gridCanvas.Width, 0, paint);
for (int i = 0; i <= (gridCanvas.Width - gridoffsetX) / pxPerSquare; i++)
{
canvas.DrawLine(i * pxPerSquare + gridoffsetX, 0, i * pxPerSquare + gridoffsetX, gridCanvas.Height, paint);
}
for (int i = 0; i <= (gridCanvas.Height - gridoffsetY) / pxPerSquare; i++)
{
canvas.DrawLine(0, i * pxPerSquare + gridoffsetY, gridCanvas.Width, i * pxPerSquare + gridoffsetY, paint);
}
}
}
,最后是原始的油漆事件
private void Pb1_PaintSurface(object sender, SKPaintGLSurfaceEventArgs e)
{
win2.UpdateDrawing(); //Just calls .Invalidate() on pb2
painter.Update(e, false);
}
examplepicture
In my application, there are 2 windows and both contain a PictureBox. The first (pb1) allows interaction and the image can be changed through click- and mouseMove-events. These events call pb1.Invalidate(); which works fine.
I want the second PictureBox (pb2) to redraw as well so I call pb2.Invalidate() from the paint-event of pb1. [Just for context, the second PictureBox shows nearly the same Image but on a bigger scale and some parts of the drawing will be left out in the future so I use the same Method in both paint events which decides what to draw and what not]
It works but it's "laggy" and I want it to be as smooth as the paint on the first PictureBox. I reduced the paint event just to a grid for test purposes.
- Both windows are double buffered.
- I tried replacing the picture boxes with SKGLControls from SkiaSharp (which should have better performance). The example code still uses the SkiaEvents so don't be confused if the problem occurs with both controls.
- I tried to use .Update() or .Refresh() instead of .Invalidate() but i guess its to much to handle, the application just crashes..
Here is the method that is called by both OnPaint events
public void Update(SKPaintGLSurfaceEventArgs e, bool bigscreen)
{
SKCanvas canvas = e.Surface.Canvas;
canvas.Clear(SKColors.Beige);
//Zoom to specified area
SKMatrix matrix = SKMatrix.Identity;
if (!bigscreen)
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(canvasSize / (float)zoomArea.Width, canvasSize / (float)zoomArea.Height));
}
else
{
matrix = matrix.PostConcat(SKMatrix.CreateScale(bigCanvasSize / (float)zoomArea.Width, bigCanvasSize / (float)zoomArea.Height));
}
matrix = matrix.PreConcat(SKMatrix.CreateTranslation(-zoomArea.X, -zoomArea.Y));
canvas.SetMatrix(matrix);
DrawGrid(canvas);
}
and the grid-draw method
private void DrawGrid(SKCanvas canvas)
{
using (SKPaint paint = new SKPaint() { IsAntialias = true,Color=SKColors.LightGray,StrokeWidth = 1})
{
canvas.DrawLine(0, 0, 0, gridCanvas.Height, paint); //Size gridCanvas is always the same at the moment and defines the space where the grid is drawn
canvas.DrawLine(0, 0, gridCanvas.Width, 0, paint);
for (int i = 0; i <= (gridCanvas.Width - gridoffsetX) / pxPerSquare; i++)
{
canvas.DrawLine(i * pxPerSquare + gridoffsetX, 0, i * pxPerSquare + gridoffsetX, gridCanvas.Height, paint);
}
for (int i = 0; i <= (gridCanvas.Height - gridoffsetY) / pxPerSquare; i++)
{
canvas.DrawLine(0, i * pxPerSquare + gridoffsetY, gridCanvas.Width, i * pxPerSquare + gridoffsetY, paint);
}
}
}
and finally the original Paint Event
private void Pb1_PaintSurface(object sender, SKPaintGLSurfaceEventArgs e)
{
win2.UpdateDrawing(); //Just calls .Invalidate() on pb2
painter.Update(e, false);
}
So my question is: Is there a way to make both controls draw at nearly the same time without delay, although I don't understand why the first PictureBox draws in real time and the second doesn't...
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
搜索一天后,我在发布后立即找到了此页面,这对我有帮助:
after searching for day i found this page right after posting, which helped me:
Onpaint events (invalidated) changing execution order after a period normal operation (runtime)