I have an application in which I can move from 1 user control to many user controls. When I was moving to many controls, I was getting flickering issues.
To solve the flickering I enabled Double Buffering via -
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
It indeed solved the issue of flickering. But introduced a new problem, In which sometimes my user control isn't painted completely. A black window is appeared. To solve this, I need to minimize and maximize the software and it appears properly.
What I think is that, while double buffering is painting all the user
controls at one shot, One or more user control is still generating its
controls. And at the time of master painting, that control was not
ready.
Here is the image for getting proper idea -
As shown in image, There is one form, containing 4 user controls in this particular scenario. Each user control further, contains other controls/user controls.
What is probably going wrong in this issue?
I solved this by changing TrasnsparencyKey in form design from black to another color but not black, try one color that you are not using.
Related
so I'm challenging myself by making a game-engine using GDI.
So far I've managed to make made a few games using GDI - however I have recent hit a problem I'd like some help with.
I have implemented a UI system and have found out that the GDI Translate function moves the entire canvas. Subsequently all my mouse coordinates are offset causing my UI system to not work as expected.
Question: Is there any way to make a Panel transparent on the Paint method?
I have tried to set the clear colour to transparent but that only makes the panel black.
I cannot point to a source for this, but I did some testing now and my explanation is as following:
When I set the BackgroundColor of the panel to Colors.FromArgb(50,0,0,0) then this worked, because whenever I changed the Backgroundcolor of the Form the panel lives on, then the color of the form shined through the panel.
But: the other controls that lived behind this panel have not been visible all the time. I am sure that for performance reasons the rendering of the controls only happens if they are visible to the user, that means they are not coverd by an other control. So the color of the form is shining through because the transparent color actually works, but the controls behind the panel are not rendered because they are covered by an other control.
You have to write your own control:
public class TransparentPanel : Panel
{
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
}
this tells windows, that the control is transparent and the controls that are are in z-order behind this control have to be rendered, too.
I have a TabControl in which I add / remove several TabPages.
I get flickering issue when I add enough pages so that the navigation buttons have to be shown.
I have no flickering at all when the navigation buttons (2 arrows to navigate left - right) are not shown. The flicker is in no way related to resize of the form or pages being added.
I have tried:
DoubleBuffering
SetStyles(... all the params to increase performance)
EDIT: In my main WinForm, I added this code to prevent a rendering bug when resizing my window:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
When removed, I no longer get the flickering in my TabControl. It seems that I will have to live with the resizing rendering bug as it is more convenient that a constant flicker.
You left out an important detail. This question strongly suggests you did more than you described, you are also overriding the CreateParams property in your form to turn on the WS_EX_COMPOSITED style flag for the window. It enables double-buffering for the form and all of its controls, a good way to suppress flicker in general.
But it can have some detrimental side-effects. TabControl is in fact a trouble-maker, something messed up about the way it renders that is incompatible with WS_EX_COMPOSITED. Once too many tabs are added and the navigation buttons appear, it starts to constantly redraw itself. Perceived as rapid flicker. The native tab control renderer has lots of bugs, the Microsoft team that wrote it did a very lousy job.
There is no known workaround for this bug, you'll have to settle for a lesser alternative.
Hi May be I am a bit late to answer, but I used this.Multiline = true; in my TabControl. This will allow TabControl to automatically adjust Tabs in multiline in case number of tabs goes more that available visual space.
You shall use this feature unless you have very specific requirement to keep all tabs in a single line.
The code above helped me resolved Tab flickering issue.I have two tabs in total (in one tab control).Tab names are being redrawn in a loop. The issue is more evident as form(window)'s area is increased.
I am using a library in which enables me to animate movement of WinForm elements (linked below), when I use it to move a transparent panel across the form (which has a picture background) there is an extraordinary amount of tearing.
I believe the fix is to get winforms to refresh at a rate of 30fps without being laggy. I tried settings a timer to do This.Refresh(); at 30 times a second but it just ended up with slow loading. So how would I achieve a nice refresh rate of the form?
The link described above is here -> http://code.google.com/p/dot-net-transitions/wiki/CodingWithTransitions#Creating_a_transition_that_works_on_a_single_property
Here is an example of the tearing. It might have something to do with the fact that the panel's backcolor is set to "transparent"
http://screencast.com/t/XIr3NkGI
I used this ages ago when I had trouble with controls on a form flickering, in my case there were many controls and when loading the form the controls would flicker quite badly.
In the end I used this:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Paste that in your form.
It activates double buffering at the form level and for all controls within it.
HOWEVER, while it stopped my flickering issue it greatly reduced the speed at which the forms elements seemed to move as they don't get drawn until they are 100% ready.
I guess you can try and see if it suits your situation.
I have a PNG file that displays crosshairs in a picturebox on my winform. I have created a user control that contains another small picture box (for a green dot), and a label.
What i want to do is place the user control over the picture box so that only the dot and label are visible. and the square edges of the control are invisible.
The dot has white edges since the png is actually square, so i attempted to set the Transparency key to be white, but when i add the control to my picture box, everything that is white is transparent.
I thought that if i colored around the edge of my dot with a color, then i can match that with the transparency key, but the colors have to be exact (right?), and my only method of painting is in windows paint, so i can't know if have matched the colors. Any help?
The problem you are running into is that WinForms controls do not support true transparency, and getting them to do so can be a bit tricky. What they do is paint the child control under themselves (when transparency is enable via SetStyle), but this has its own quirks. You should first try something like this:
// in your custom control class...
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
I have found this method to be more reliable than the following, but you should try this as well:
public MyTransparentControl()
{
SetStyle( ControlStyles.SupportsTransparentBackColor |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true );
BackColor = Color.Transparent;
}
As an alternative approach, have you considered using WPF instead of WinForms? I know this is not always an option, but if it is you will make your life a whole lot easier as WPF controls support transparency and control layering out of the box.
I added this to my form's constructor code:
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
But it still shows ugly artifacts when it loads the controls, whenever they change (the form and its components change (need updating) often).
What do I need to do differently?
This only has an effect on the form itself, not the child controls. If you have a lot of them then the time they need to take turns painting themselves becomes noticeable, it leaves a rectangular hole where the control goes that doesn't get filled up until the child control gets it turn.
What you'd need to combat this is double-buffering the entire form and the controls. That's an option available since Windows XP which made the WS_EX_COMPOSITED style flag available. Paste this into your form to turn it on:
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
It doesn't speed up the painting at all, but the form snaps onto the screen after a delay. Eliminating the visible paint artifacts. Really fixing the delay requires not using controls. Which you'd do by using the OnPaint method to draw the 'controls' and making the OnMouseClick event smart about what 'control' got clicked by the user.