Search code examples
c#winformsbitmappaintsplitcontainer

C# How to force Paint event of Panel1 and Panel2 complete at the same time?


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();
    }

Solution

  • 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