Click here to Skip to main content
Click here to Skip to main content

Visual Studio .NET style status bar

By , 22 Feb 2004
 

Introduction

I have always loved the Visual Studio .NET style interface, and when I tried to "copy" it to my own project, the owner drawn StatusBarPanel always flickered when I try some fast update like displaying mouse positions when mouse is moving. This project demonstrates how to do a flicker free drawing of the status bar in C#, it looks like the same as the Visual Studio .NET one, except mine cannot display animated icon yet (Visual Studio .NET can show an animated icon when you save files).

How to make it flicker free

Owner drawn status bar, we need to overwrite the OnDrawItem or add an event handler for DrawItem.And the Style of the StatusBarPanel must set to StatusBarPanelStyle.OwnerDraw.

//
// by event handler
//
MessagePanel.BorderStyle = StatusBarPanelBorderStyle.None;
MessagePanel.Style = StatusBarPanelStyle.OwnerDraw;
this.DrawItem +=new StatusBarDrawItemEventHandler(
  DotNetStatusBar_DrawItem);
...
protected void DotNetStatusBar_DrawItem(
  object sender, StatusBarDrawItemEventArgs sbdevent)
{

  // some drawing codes for a panel
}

This function can do the owner drawing but still cannot avoid flickering. This is because each time the status bar needs to be redrawn, its background got redrawn first. Even if we overwrite the OnPaintBackground function, or we set the style to ControlStyles.Opaque, the background still keeps getting redrawn.

My way of avoiding flicker is to use a double buffer, i.e. set the style to ControlStyles.DoubleBuffer.

this.SetStyle( ControlStyles.AllPaintingInWmPaint 
    | ControlStyles.UserPaint 
    | ControlStyles.DoubleBuffer, true);

To fully enable double-buffering, you must also set the UserPaint and AllPaintingInWmPaint style bits to true. And just because of this UserPaint style, we must overwrite the OnPaint function. In this function, you need to do all the status bar and panels drawings by yourself.

protected override void OnPaint(PaintEventArgs e) 
{ 
  int iStart = 0; 
  StatusBarDrawItemEventArgs ea = 
    new StatusBarDrawItemEventArgs(e.Graphics,Font, 
    new Rectangle(iStart,2,MessagePanel.Width-2,Height-1),
    1,DrawItemState.Default,MessagePanel); 
  OnDrawItem(ea);
  ...
}

Things to do

I did this code only for my own project, so it is not very general. Things can be done like make it a custom control compatible with Visual Studio .NET. Also more exploration can be done on how to display animated icons, progress bars...

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Zhang Songling
Web Developer
China China
Member
Zhang Songling is a programmer, he graduated from National University of Singapore at 2003. Now he is working in a high tech semicon software company in Singapore.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Layout  Per page   
General很好! Pinmemberqingtianyu911 Jan '08 - 13:55 
GeneralGrats... this did it :) PinsussRoland Gollenbeck16 Dec '04 - 1:25 
GeneralDetermining screen size for resizing grip in OnResize() method PinsussRussian Percussion22 May '04 - 4:13 
One suggestion I would make is to change the way the toolbar object determines the screen size for resizing grip in the OnResize() method.
 
Currently your class uses SystemInformation.VirtualScreen.Width to determine the Width of the screen, which on multimonitor desktops like mine will give the Width of the whole desktop (ex 3 monitors x 1280 = 3840). This number is then compared to the Width of the toolbar that is based on the width of just one monitor (1280). As the result, the resizing grip is never deactivated - even when one maximizes the app to any one screen. So, you get some strange behavior in maximized mode.
 
So, I replaced the call to SystemInformation.VirtualScreen.Width with call to
SystemInformation.WorkingArea.Width. This way one correctly can determine the Width of the working area regardless of the overall size of the virtual desktop. In this fashion, the resizing grip is turned off correctly in maximized mode.
 
This change should work for single and multimonitor users.
 
Russian Percussion
GeneralRe: Determining screen size for resizing grip in OnResize() method PinmemberABOCuk11 May '05 - 1:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 23 Feb 2004
Article Copyright 2004 by Zhang Songling
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid