I have a SplitContainer (a NonFlickerSplitContainer one to be exact) and I treat its both panels as a single canvas to paint on. I use Graphics.DrawImage method to paint bitmaps on the panels separately. I refresh Panel1 first, then Panel2 which results in vertical/horizontal tearing - painting of Panel1 ends, then painting of Panel2 starts - that's the reason. What would be the solution to my problem? I use a splitContainer as an output to a "bitmap video stream" with before/after capability. Maybe I can freeze UI somehow until Panel2_Paint ends?
private void splitContainer_Panel1_Paint(object sender, PaintEventArgs e)
{
if (frameA != null)
{
if (ORIGINAL_SIZE_SET)
e.Graphics.DrawImage(frameA, 0, 0);
else
e.Graphics.DrawImage(frameA, 0, 0, ClientSize.Width, ClientSize.Height);
}
}
private void splitContainer_Panel2_Paint(object sender, PaintEventArgs e)
{
if (frameB != null)
{
//...
if (ORIGINAL_SIZE_SET)
e.Graphics.DrawImage(frameB, x, y);
else
e.Graphics.DrawImage(frameB, x, y, ClientSize.Width, ClientSize.Height);
}
}
private Bitmap frameA = null;
private Bitmap frameB = null;
private void RefreshOutput(bool refreshClipA = true, bool refreshClipB = true)
{
if (refreshClipA)
{
frameA = GetVideoFrame(...);
//...
}
if (refreshClipB)
{
frameB = GetVideoFrame(...);
//...
}
if (refreshClipA)
splitContainer.Panel1.Refresh();
if (refreshClipB)
splitContainer.Panel2.Refresh();
}
I have experienced it is impossible to make sure that two separate panel.Paint() events complete at the same moment, at least not in a WinForms project. The only solution that worked for me is the suggested by DonBoitnott. I use a single panel now and simulate a splitcontainer behavior.
If I were answering this, I would suggest you ditch the splitcontainer and render to a single surface, that way you are always in a single Paint event and you simply region it off and draw accordingly. – DonBoitnott Feb 17 '16 at 17:51