How to avoid screen flickering? - c#

I am making a windows form application and mainly my screen is divided between 3 parts like
===========================================================================
Top panel (it doesn't flicker)
===========================================================================
|| || 'it has a panel & panel contains a table layout,this tabble layout'
|| || 'has a picture box and a label, picture & text of label is'
|| ||'changed on the click of side bar menu' (PROB: this flickers a lot)
||side bar ||==============================================================
||(doesn't ||'this part also has a panel and panel contains different table'
||flicker) ||'layouts and on the click of a menu, related table layout is shown and'
|| ||'some of the parts of table layout are created dynamically.'
|| ||
|| || (PROB: this flickers a lot)
|| ||
i searched a lot and found this solution everywhere and i tried this
public constructor()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.DoubleBuffered = true;
DoubleBuffered = true;
SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.ContainerControl |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.SupportsTransparentBackColor
, true);
}
i also tried this
protected override CreateParams CreateParams
{
get
{
CreateParams handleParam = base.CreateParams;
handleParam.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return handleParam;
}
}
it changes the whole background of my screen to black color.
but still problem remains the same, can someone tell me how to solve this problem and where i am doing mistake ?
Thanks a lot in advance.

Without more to go on, my gut says that you are either adding a lot of data do those areas or there is a lot of resizing going on.
try this anywhere you update the screen ( adding rows to listviews/boxes/etc ) or resize the screen, or anything else that will cause the screen to redraw.
ex:
public void something_resize(object sender, EventArgs e)
{
try
{
this.SuspendLayout();
// Do your update, add data, redraw, w/e.
// Also add to ListViews and Boxes etc in Batches if you can, not item by item.
}
catch
{
}
finally
{
this.ResumeLayout();
}
}
Its important to put the ResumeLayout() call in the finally block, because if an exception occurs for w/e reason, you want your window to layout, regardless of what you do with the exception.

Related

Flickering with transparent panel

I've created a simple program and now i'm in the stages of doing my designing. I've got a multiple Panels which i make visible / invisible to switch between "tabs" (EG. 1 panel for the login screen and 1 panel for the create account screen). Now i've made these panels invisible because i want them just as containers to be able to quickly move around controls and create buttons in.
My problem is that i've set my forms background image to a image i made in photoshop and whenever i switch between panels it flickers, whenever i just use a system color (white,black) this doesn't happen.
Is there any way for me to remove the flickering?
i've tried :
Setting double buffer to true
protected overrideing OnPaint, CreateBackground, and Createparam
my code is extremely basic :
private void btnNewAcc_Click(object sender, EventArgs e)
{
PanelNewAccount.Visible = true;
PanelLogin.Visible = false;
}
Try to setting the form property DoubleBuffered to true, in winforms the flickering usually happens because the GDI+ is trying to draw the control(s) a lot of times so DoubleBuffering you graphics should help in such cases
form.DoubleBuffered = true;
Thanks to Patrick i've solved my problem,
instead of using panels i'm using a TabControl and i assigned the same background to each tab.
Just as easy to add dynamic buttons as well.
Same features as panels but without the flickering.
#region .. Double Buffered function ..
public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
aProp.SetValue(c, true, null);
}
#endregion
#region .. code for Flucuring ..
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
#endregion
Even though i am late but if somebody else is also suffering from the same problem then this code fixed the flickering for me even though i dont know how it works.
I found it here.
Add the above code snippet in your program and in the contructor of your app add this line:
SetDoubleBuffered(YourPanelName);
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
code copy from codeproject solved my problem.

Why is the SizingGrip of StatusStrip not showing?

I want to add a StatusStrip to a UserControl and resize this UserControl at runtime. Here is how I add the StatusStrip.
StatusStrip sb = new StatusStrip();
sb.BackColor = System.Drawing.SystemColors.ControlDark;
sb.Dock = DockStyle.Bottom;
sb.GripMargin = new Padding(2);
sb.SizingGrip = true;
sb.GripStyle = ToolStripGripStyle.Visible;
sb.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
this.Controls.Add(sb);
The StatusStrip is displayed at the bottom of the UserControl. However there is no SizingGrip (little Triangle) in the right bottom corner of the StatusStrip. Why not?
It's not showing up because a UserControl is not a sizable control at runtime. The StatusStrip, nay more specifically the sizing grip, was built to support the Form control.
Here is the code for ShowSizingGrip, a private property used during paint:
private bool ShowSizingGrip
{
get
{
if (this.SizingGrip && base.IsHandleCreated)
{
if (base.DesignMode)
{
return true;
}
HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);
if (rootHWnd.Handle != IntPtr.Zero)
{
return !UnsafeNativeMethods.IsZoomed(rootHWnd);
}
}
return false;
}
}
at this point I can see two point of interest. First, HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);, I can't test this class because it's internal, but there's a really good chance it's not going to return a window. However, even if it did, if said window was currently maximized, !UnsafeNativeMethods.IsZoomed(rootHWnd);, the sizing grip wouldn't show either.
My educated guess -- your window is maximized. I make that assumption because it appears Cody Gray was able to make it show up on a UserControl.

Tab in Image with hotspots

I have a problem which I don't know a work around for.
I'm creating a program for the company I work. The program has to write down a deliverypage for sendings we transport because right now the company has over 100 excel files, for every delivery one.
What I got now is a picturebox with an Image and that image has 16 hotspots.
with hotspots I mean Rectangles(Bounds) to know which part on the image the user has clicked on because that part needs to be selected. so far no problem. but my only problem is when hitting the Tab button.
How can I switch from Rectangle to rectangle on the image to the other Rectangle when hitting the tab button. because because there is no tabstop on a rectangle bound.
I already tried adding custom controls using tabstop and that worked great but then I had this problem that the data that has to be written in the content is limited to the area. so I need to paint it directly on the image so using controls is no option for me.
Hope my description is clear enough and else feel free to ask.
I Managed to solve my own problem with underlaying code
protected override bool ProcessDialogKey(Keys keyData)
{
int selectionIndex = pBoundsCollection.IndexOf(pSelection);
if (keyData == Keys.Tab)
{
while (selectionIndex++ <= pBoundsCollection.Count)
{
if (selectionIndex >= pBoundsCollection.Count)
{
selectionIndex = 0;
pSelection = (CMRField)pBoundsCollection[selectionIndex];
Refresh();
break;
}
if (((CMRField)pBoundsCollection[selectionIndex]).IsSelectable)
{
pSelection = (CMRField)pBoundsCollection[selectionIndex];
Refresh();
return false;
}
}
}
return base.ProcessDialogKey(keyData);
}

Application Title in Taskbar but not Titlebar

This is a strange thing I'm doing, but how can I set the title of a winform form in the taskbar, but not in its titlebar?
A possible solution (it works fine for me) it's to override the CreateParams property and set the caption to be displayed in the taskbar:
protected override CreateParams CreateParams
{
get
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
// Extend the CreateParams property of the Button class.
CreateParams cp = base.CreateParams;
// Update the button Style.
cp.Style &= ~0xC00000; //WS_CAPTION;
cp.Caption = PRODUCT_NAME;
return cp;
}
}
I hope that works for you,
Lisa
Okay, so my temporary work around is this:
At runtime/design-time, Clear the Text Property for the Form (Form1, or whatever form this applies to), and when the Minimize, or Hide() events are triggered, change the Text Property to display a Title. So, when the form is hidden or minimized, you won't be able to see the titlebar anyway, but you will be able to see the caption on the Taskbar! And when the Form is later maximized, or when the Form.WindowState == WindowState.Normal, then clear the Text Property again. :-)
I wonder if this is the approach MS took!?
Edit:
Okay, sweet, I've got some working code of yumminess:
If you're using Visual Studio, go to Design View, select the Form control, open the Properties Pane, click the Events Tab, then double-click the Resize event. The Code View should display. Inside the Resize() code that was just created, type this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
}
Step 2:
When you want to show/maximize the form again, simply edit the above so it looks like this:
private void Form_Resize( object sender, System.EventArgs e )
{
if( this.WindowState == FormWindowState.Minimized )
this.Text "Some uber-awesome title.";
else if(this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized)
{
this.Text = String.Empty; // Or, you can use: this.Text = "";
}
}
However, this does not completely solve my problem yet. It still doesn't display the Title in the Taskbar when the Form is Visible to the user (because the Text property of the Titlebar is empty.
A workaround could be drawing your own form title bar. That way you won't need to change the actual title that's shown in Taskbar.
This question is about WPF rather than Winforms but it's applicable: Set a taskbar text different from the Window title in wpf

C# transparent PNG for buttons, panels...how?

I have being searching a lot, seen a few examples but they don't work at least for me. This is what I need: in my application I need to use transparent PNG icons for the toolbars and also for draggable visual objects representations, ie, 72x72 "page" icon which can be dragged around and possibly over all elements in the client area. For the first I was thinking about using a button, set its BackImage to the transparent PNG and put BackColor as "transparent": it won't work, the button always show a solid color behind. As for the panel, the same problem: I can put a transparent PNG as background image but the control never looks "transparent" where the PNG has transparent areas. I think the same with a picturebox and any other control allowing image backgrounds. So I guess, it is really about making a control's background transparent...Any ideas?
I don't care if I need to create some sort of custom "image button" or "image panel" --whatever-- to have truely PNG transparent buttons, panels, etc! Also, please note, it is about PNG transparency, using the alpha channel, not transparent pixels, which at this ages, sucks IMHO for decent GUIs.
Cheers
litium
Ok I found the following code whith works not only for panels but also for buttons and I guess other controls --except PictureBox:
public class TransparentPanel : Panel <==change to Button for instance, and works
{
Timer Wriggler = new Timer();
public TransparentPanel()
{
Wriggler.Tick += new EventHandler(TickHandler);
this.Wriggler.Interval = 500;
this.Wriggler.Enabled = true;
}
protected void TickHandler(object sender, EventArgs e)
{
this.InvalidateEx();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
protected void InvalidateEx()
{
if (Parent == null)
{
return;
}
Rectangle rc = new Rectangle(this.Location, this.Size);
Parent.Invalidate(rc, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// Do not allow the background to be painted
}
}
Works for me 100%! Doesn't seems to work for PictureBoxes.

Categories