Click here to Skip to main content
15,891,708 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I want to set the DoubleBuffered style of a Panel in a Forms application to avoid flickering when painting it.

This requires to call its SetStyle method. This method being protected, you need to derive a new class from Panel.

Unfortunately when you do this, the Designer cannot recognize the Panel object anymore and gets screwed.

Who knows of a workaround ?
Posted

I have found the following hack:

1) Derive a class from Forms::Panel to expose the SetStyle method as public. Do this outside of Form1.h.

C#
public ref class MyPanel :  public System::Windows::Forms::Panel
{
public:
    void SetStyle(System::Windows::Forms::ControlStyles flag, System::Boolean value)
    {
        System::Windows::Forms::Control::SetStyle(flag, value);
    }
};


2) When it comes to changing the panel behavior (I do that in the main form constructor), cast the panel pointer the new class type.

static_cast<MyPanel^>(panel1)->SetStyle(ControlStyles::AllPaintingInWmPaint, true);
static_cast<MyPanel^>(panel1)->SetStyle(ControlStyles::DoubleBuffer, true);


This way, the code that the Designer parses remains perfectly untouched.
 
Share this answer
 
v4
Comments
Dmitri Novikov 19-Jun-12 19:12pm    
Didn't succeed this in my C# 2010 game project:( Can't put here exact compiler message because I have a russian version. But it says something like can't access SetStyle because it's a protected member. Any suggestions?
Dmitri Novikov 19-Jun-12 19:21pm    
Ah, all posible. Maybe I'm just too weak in C#: this is my first real project using this language and .NET framework. Just do not know how to access parent's method with the same name. When I changed to MySetStyle, all seems to go well, but I will continue tomorrow, it's time to be asleep:)
YvesDaoust 20-Jun-12 10:13am    
In C#, I work like this:

in Form1.cs, declare a class like this:

// Trick to allow double buffering
public class DoubleBufferPanel : Panel
{
public DoubleBufferPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
}

Then in Form1.Designer.cs, replace the occurrences of the Panel type by the this newly defined class (two places).
This is what I have done (Visual C# 2010 Express) and it works perfectly fine.


  • Create a new WinForm application project
  • Drag a panel onto the form
  • Add an user control to that project
  • Drop some controls onto that UserControl
  • Add a public method to give access to SetStyle
  • Open the *.designer.cs file in the editor and replace Panel by the new user control and also rename the variable and update the code accordingly

    • Change the type at declaration
    • Change variable name and let Visual Studio update references
    • Update the construction of that object to create the newly created user control
    • Update the name in the comment for that control
    • Update the name property of that control

  • Build and run the application
  • Click on the tab with the designer


Sure enough, my user control with any controls I dropped into it was properly show in my form.

Sometime, it might happen that a Clean or a restart of Visual Studio is required after having some problems but it is rare.
 
Share this answer
 
v4
Comments
Espen Harlinn 17-Jul-11 18:30pm    
Excellent effort, my 5+
YvesDaoust 18-Jul-11 2:27am    
Sorry, I should have mentioned using Visual C++.

This does not work under Visual C++ 2005 nor 2008.

For the sake of being sure, I did retry all you say (which is essentially what I was doing before plus extra renamings). The designer ceases to recognize the code and displays an error message.

Thank you anyway.
YvesDaoust 23-Jul-11 15:13pm    
This works fine with both C# and Visual Basic. Smart compilers !

It is even possible to put the derived class declaration with that of the main form. This keeps the solution very compact.
Once the application is compiled, the designer should works properly again. So you should close the designer, build the application and open the designer again.
 
Share this answer
 
Comments
YDaoust 17-Jul-11 3:25am    
I wish it were so, but it is not. My guess it that when parsing the source code, the Designer comes across an unknown class and does not know what to do with it.

It would be nice to find a way of changing the Panel style bits differently than with SetStyle.
Philippe Mori 17-Jul-11 8:33am    
Which version of Visual Studio are you using? Visual Studio 2010 is better for handling designer errors. Less problems and more usefull error reporting.

By the way sometimes, you have to "clean all" or event restart Visual Studio.

Otherwise, you have to ensure that your type is accessible and that you have updated it everywhere it need to be updated.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900