Click here to Skip to main content
15,890,670 members
Articles / Programming Languages / C#
Article

InfoBarLite Control

Rate me:
Please Sign up or sign in to vote.
4.33/5 (13 votes)
18 Sep 20024 min read 115.9K   2.2K   69   18
This article shows how to create a Windows.Forms control by using C#.

Sample Image 1 - InfoBarLite1.jpg

Sample Image 2 - InfoBarLite2.jpg

Introduction

Ever since Microsoft started using a nice GUI style that shows brief information at the top of setup forms, I wanted to have one of my own. The screen shot shown above display a sample of such a control. I first created this control as an OCX with VB6 and used it in several projects. VB6 version required heavy use of Win32 API functions. However, to learn C# syntax, I decided to create the same control, I call it InfoBarLite, with this new language. After starting to code, I found out that life was much better with C#.

The control has some very nice features to make things easier:

  • The control can have both a background image and a separate image.
  • The image can be aligned in 9 different ways. Additionally, the image can be positioned by using x and y offset properties.
  • Two different text properties are provided each of which can have multiple lines separated by Environment.NewLine character.
  • Each text property has its own Font, ForeColor, OffsetX, and OffsetY properties.
  • Background color of the control can be either solid or gradient.
  • The control can have 9 different border styles for all sides or for each side.
  • It can be used either as a header bar or as a side bar.

Details

The InfoBarLite control is derived from System.Windows.Forms.UserControl as shown below:

C#
public class InfoBarLite : System.Windows.Forms.UserControl
{    // Actual code
    ...
}

The most interesting part of the control is OnPaint event as this is the usual case for owner-drawn controls. First, the background information is drawn. This information is defined by BackStyle, BorderSide, and BoderStyle properties. One point I want to stress out is that the behavior of the control. if the BackStyle is Gradient, the background image is not drawn. This means that BackStyle property has precedence over BackgroundImage property. In contrast, if the BackStyle is Solid, the BackColor property is ignored. This behavior is by design. Of course, it can easily be changed by modifying the overridden OnPaint event. Now, here is the OnPaint method:

C#
/// <summary>
/// Overloaded Paint method
/// </summary>
/// <param name="pe">PaintEventArgs</param>
protected override void OnPaint(PaintEventArgs pe)
{
   // First, repaint the base class
   base.OnPaint(pe);

   Rectangle r = this.ClientRectangle;

   // Draw the background and border(s)
   switch( this.BackStyle )
   {
      case BackStyle.Gradient:
         LinearGradientBrush gb = new LinearGradientBrush(r,
                                        this.GradientStartColor,
                                        this.GradientEndColor,
                                        this.GradientMode);
         if(this.BorderSide == Border3DSide.All)
         {
            ControlPaint.DrawBorder3D(pe.Graphics, r,
               this.BorderStyle, this.BorderSide);
               r.Inflate(-2, -2);
            pe.Graphics.FillRectangle(gb, r);
         }
         else
         {
            pe.Graphics.FillRectangle(gb, r);
            ControlPaint.DrawBorder3D(pe.Graphics, r,
                  this.BorderStyle, this.BorderSide);
         }
         gb.Dispose();
         break;

      case BackStyle.Solid:
         if(this.BorderSide == Border3DSide.All)
         {
            ControlPaint.DrawBorder3D(pe.Graphics, r,
                    this.BorderStyle, this.BorderSide);
            r.Inflate(-2, -2);
            SolidBrush sb = new SolidBrush(this.BackColor);
            pe.Graphics.FillRectangle(sb, r);
            sb.Dispose();
         }
         else
         {
            ControlPaint.DrawBorder3D(pe.Graphics, r,
                     this.BorderStyle, this.BorderSide);
         }

         break;

      default:
         ControlPaint.DrawBorder3D(pe.Graphics, r,
                     this.BorderStyle, this.BorderSide);
         break;
   }

   // Set variables for Image and Text drawing
   StringFormat fmt = new StringFormat();
   fmt.FormatFlags = StringFormatFlags.MeasureTrailingSpaces |
   StringFormatFlags.DisplayFormatControl |
   StringFormatFlags.FitBlackBox;
   fmt.Trimming = StringTrimming.EllipsisCharacter;

   // Rectangle variables that will be calculated
   RectangleF rImage = new RectangleF(0,0,0,0);
   RectangleF rText1 = new RectangleF(0,0,0,0);
   RectangleF rText2 = new RectangleF(0,0,0,0);

   SizeF sizeText1 = pe.Graphics.MeasureString(this.Text1,
                   this.Text1Font, ClientRectangle.Size, fmt);
   SizeF sizeText2 = pe.Graphics.MeasureString(this.Text2,
                   this.Text2Font, ClientRectangle.Size, fmt);

   // Calculate the rectangles before starting to draw
   this.getRects(ref rImage, ref rText1,
                           sizeText1, ref rText2, sizeText2);

   // Draw the image and the texts
   if(this.Enabled)
   {
      int iImageWidth = 0;

      if( this.m_Image != null )
      {
         pe.Graphics.DrawImage(this.m_Image, rImage);
         iImageWidth = this.m_Image.Width;
      }

      SolidBrush sb = new SolidBrush(this.Text1ForeColor);
      pe.Graphics.DrawString(this.Text1,
              this.Text1Font, sb, rText1, fmt);

      sb = new SolidBrush(this.Text2ForeColor);
      pe.Graphics.DrawString(this.Text2, this.Text2Font,
              sb, rText2, fmt);

      sb.Dispose();
    }
    else
    {
       if( this.m_Image != null )
          ControlPaint.DrawImageDisabled(pe.Graphics,
                            this.m_Image, (int) rImage.X, (int) rImage.Y,
                            SystemColors.ControlLight);

       ControlPaint.DrawStringDisabled(pe.Graphics,
                            this.Text1, this.Text1Font,
                            SystemColors.ControlLight,
                            rText1,
                            fmt);

      ControlPaint.DrawStringDisabled(pe.Graphics,
                            this.Text2, this.Text2Font,
                            SystemColors.ControlLight,
                            rText2,
                            fmt);
   }
}

Usage

It should be very easy to use this control. Just drop it in a form, set the desired properties, and that's all. A sample which is very similar to Nero's screen is shown below:

Sample Image 2 - InfoBarLite3.jpg

Figure 3 - A sample demo screen showing the control as a side bar and as a header bar.

Know issues/limitations

There are some issues that need to be fixed and/or added.

  • When the control is used as a sidebar, text properties are not drawn rotated (vertical), but this is by design.
  • The Font property inherited from UserControl class should not be visible to the user. Currently, I don't know how to do it; therefore, any suggestions will be appreciated.
  • When the Enabled property is changed through the property window (in design mode), this change is not reflected to the control. On the other hand, if this property is changed via code, the control acts as expected. Once again, I require suggestions on this issue.
  • The last limitation is that the control is not globalization aware. In VS IDE, if you set the Form's Localizable property to True, the IDE automatically adds code to retrieve the correct text of native controls (comes with VS.NET) that will reflect the CurrentCulture via resource manager. I guess this is the easiest way to localize an application. Currently, the InfoBarLite doesn't cooperate with the IDE to accomplish this task. If someone knows how to do it and sends the solution, I can update the control to benefit everybody.

Conclusion

Hopefully, the InfoBarLite control will make my fellow developers' life easier as it did mine. It will also allow you to add a very nice user interface feature that will help you to increase end-user experience. If you look at Figure 1, this control will increase the understandability of the forms we create for users, as they will now have more descriptive information about what is needed from him/her. Traditionally, this kind of information is displayed in a StatusBar control. However, most of the users are not happy, at least my users, because they are being forced to read such small letters. The InfoBarLite control attempts to solve aforementioned usability problems. It can display two different styles of text and an image. The image might describe the task required to be achieved better than text as most people tend not to read descriptions. It's suggested to be used in dialog boxes, but, of course, it's up to you.

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


Written By
Software Developer (Senior)
Germany Germany
I have MS degree in Computer Science. I graduated from Oklahoma City University, OK, USA.

My current skills are C#, ADO.NET, ASP.NET, VB6, Java, C++, SQL Server 2000, and Oracle.

Comments and Discussions

 
General.NET 2.0 Pin
ocidop11-Feb-07 8:45
ocidop11-Feb-07 8:45 
GeneralProblem adding an img by defaul Pin
vbinfo6-Oct-04 1:20
vbinfo6-Oct-04 1:20 
GeneralEnabled Property Pin
Sean Woodward7-Mar-03 16:54
Sean Woodward7-Mar-03 16:54 
Generalusing {} Pin
ClearlyDotNet11-Dec-02 5:21
ClearlyDotNet11-Dec-02 5:21 
Generalclipping Pin
NiceGuyUK2-Oct-02 11:01
NiceGuyUK2-Oct-02 11:01 
GeneralLocalization Pin
Anonymous19-Sep-02 2:33
Anonymous19-Sep-02 2:33 
GeneralRe: Localization Pin
Anonymous23-Sep-02 22:01
Anonymous23-Sep-02 22:01 
GeneralRe: Localization Pin
Member 29688513-Jul-06 7:39
Member 29688513-Jul-06 7:39 
GeneralName conflict... Pin
Ray Cassick7-Sep-02 8:01
Ray Cassick7-Sep-02 8:01 
GeneralRe: Name conflict... Pin
Muhammed Inam9-Sep-02 3:38
Muhammed Inam9-Sep-02 3:38 
GeneralGreat Job! Pin
Russell Morris6-Sep-02 8:58
Russell Morris6-Sep-02 8:58 
GeneralRe: Great Job! Pin
Muhammed Inam9-Sep-02 2:54
Muhammed Inam9-Sep-02 2:54 
GeneralRe: Great Job! Pin
Anonymous19-Sep-02 2:31
Anonymous19-Sep-02 2:31 
GeneralCool! Pin
Richard Deeming6-Sep-02 6:34
mveRichard Deeming6-Sep-02 6:34 
GeneralRe: Cool! Pin
Muhammed Inam9-Sep-02 2:53
Muhammed Inam9-Sep-02 2:53 
GeneralNothing "Lite" about this control... Pin
David Stone6-Sep-02 6:17
sitebuilderDavid Stone6-Sep-02 6:17 
GeneralRe: Nothing "Lite" about this control... Pin
Muhammed Inam9-Sep-02 2:51
Muhammed Inam9-Sep-02 2:51 
GeneralRe: Nothing "Lite" about this control... Pin
Muhammed Inam9-Sep-02 3:00
Muhammed Inam9-Sep-02 3:00 

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

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