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

WinForm Style Sheet

Rate me:
Please Sign up or sign in to vote.
3.08/5 (11 votes)
22 Jun 20044 min read 131.8K   2.5K   33   10
An article on setting styles for Windows applications.

Introduction

Cascading Style Sheet (CSS) is a familiar name to all web developers. Using CSS, you can make a consistent look and feel for all the web pages, and more importantly, it provides a centralized control location which enables you to set or modify the look and feel (color, font, font size, ...) of all the web pages at once.

There is no CSS functionality defined for WinForms. There are commercial components that you can buy and integrate to your application, or you can use Windows Forms XML Parser and make the user interface by XML. But the easiest way is using inheritance.

Using visual inheritance will provide the CSS functionality for the WinForms but there are some considerations involved. In this article, you will see how inheritance works, and how you can use App.config file as a CSS.

Using the code

The following steps will show you how to make a reusable Label control:

  1. Make a new solution (call it: WinformCSS).
  2. Add a "Windows Application" project to the solution (call it: MyWinApp).
  3. Add a "Windows Control Library" project to the solution (call it: WinCSS).
  4. Inside WinCSS project, right click on UserControl1.cs and rename it ErrorLabel.cs.
  5. Inside WinCSS project, right click on ErrorLabel.cs, click on View Code, then search and replace "UserControl1" with "ErrorLabel".
  6. Use inheritance and derive your control from one of the pre existing ones. In this case, I changed:
    C#
    public class ErrorLabel :System.Windows.Forms.UserControl

    to:

    C#
    public class ErrorLabel :System.Windows.Forms.Label
  7. Save the changes.
  8. Inside WinCSS project, double click on ErrorLabel.cs. The IDE will show you a page with this message:
    To add components to your class, drag them from Server Explorer or Toolbox ...
  9. Right click on the page and choose Properties.
  10. Use the Properties window and set any property you need. In this example, I set the Font to: Verdana, size 10, bold, and set the ForeColor to "Red".
  11. Save all and build WinCSS project.
  12. Inside MyWinApp project, double click on Form1.cs.
  13. Inside the IDE toolbox, open one of the tabs, for example, "My User Controls", then right click and choose "Add/Remove Items...".
  14. Use Browse button and point to the C:\...\WinformCSS\WinCSS\bin\Debug folder, and select WinCSS.dll. It adds all the available controls in the WinCSS.dll to the ".NET Framework Components" tab. Click OK. Now "ErrorLabel" is available in "My User Controls" tab, and you can use it in any WinForm.
  15. Drag and drop "ErrorLabel" to Form1. Now, you have an inherited Label, its properties (Font and ForeColor) have been preset.

But wait, we are not finished yet.

To test this, open ErrorLabel.cs, use the "Properties Window", and change the color of the ErrorLabel from Red to Blue, and rebuild the solution.

If you go back to Form1, you see that the color of the label is still red. What happened?

The answer is inside "Windows Forms Designer generated code". VS. NET has generated this code:

C#
this.errorLabel1.Font = new 
   System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Bold, 
   System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.errorLabel1.ForeColor = System.Drawing.Color.Red;
this.errorLabel1.Location = new System.Drawing.Point(72, 24);
this.errorLabel1.Name = "errorLabel1";
this.errorLabel1.TabIndex = 0;
this.errorLabel1.Text = "errorLabel1";

As you can see, the ForeColor property has been set to Red, which means that it is overriding the predefined value. In other words, although the new color of ErrorLabel is Blue, Form1 shows the local value for the errorLabel1.

Solution

We need to override the control properties inside WinCSS project and make them read only. To do this:

  1. Open the ErrorLabel.cs code page, and go to the "Windows Forms Designer generated code" section. You’ll see:
    C#
    private void InitializeComponent()
    {
      // 
      // ErrorLabel
      // 
      this.Font = new System.Drawing.Font("Verdana", 9.75F, 
                  System.Drawing.FontStyle.Bold, 
                  System.Drawing.GraphicsUnit.Point, 
                  ((System.Byte)(0)));
      this.ForeColor = System.Drawing.Color.Blue;
    
    }
  2. Override the Font and ForeColor properties and make them read only (do not provide set {... = value ;}).
    C#
    public override Font Font
    {
      get
      {
         return new System.Drawing.Font("Verdana", 9.75F, 
                    System.Drawing.FontStyle.Bold, 
                    System.Drawing.GraphicsUnit.Point, 
                    ((System.Byte)(0)));
      }
    }
     
    public override Color ForeColor
    {
      get
      {
        return System.Drawing.Color.Blue;
      }
    }
  3. Now, if you build the WinCSS project and go back to the Form1, you’ll see that the color is Blue.

Enhancement

Till now, in order to change the style, you needed to change the code and recompile it again. But if you want to expose this functionality and be able to change the style without changing the code and rebuild the application, you need these extra steps:

  1. Add App.config to the MyWinApp project.
  2. Add the settings to the <appSettings /> section.
    XML
    <configuration>
        <appSettings>
            <!-- Setting For ErrorLabel ################################# -->
            <add key="ErrorLabelForeColorR" value="0" />
            <add key="ErrorLabelForeColorG" value="0" />
            <add key="ErrorLabelForeColorB" value="255" />
            <add key="ErrorLabelFontName" value="Verdana"/>
            <add key="ErrorLabelFontSize" value="10"/>
            <!--ErrorLabelFontStyle Valid values: 
                     Bold,Italic,Regular,Strikeout,Underline-->
            <add key="ErrorLabelFontStyle" value="Bold"/>
    
            <!--ErrorLabelFontGraphicUnit Valid values: 
                     Display,Document,Inch,Millimeter,Pixel,Point,World-->
            <add key="ErrorLabelFontGraphicUnit" value="Point"/>
            <add key="ErrorLabelFontGRI" value="0"/>
    
            <!-- End Setting For ErrorLabel ################################ -->
        </appSettings>
    </configuration>
  3. In ErrorLabel.cs file, use ConfigurationSettings.AppSettings[""] to read the values in start time and pass them to the overridden properties.

Note: In design time, you should change the settings inside the App.config, but in production, you need to change MyWinApp.exe.config file.

Summary

You can use this approach to make a library of controls such as Button, Label, RadioButton, and …, set their properties by overriding their base class properties, and make them read only. Then you can add the controls to your VS.NET toolbox and use them in your WinForm.

Any time you change the settings in your custom controls (or in the configuration file), the style of the controls in you application(s) will be updated automagically.

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
Architect
Canada Canada
I worked for the software industry as a software architect, system analyst, senior software engineer and MIS (management information system) consultant for last 10 years.

Comments and Discussions

 
GeneralMy vote of 1 Pin
FabriD13-Oct-10 2:28
FabriD13-Oct-10 2:28 
GeneralEasier way to change the default value Pin
The_Mega_ZZTer27-Aug-05 4:45
The_Mega_ZZTer27-Aug-05 4:45 
In addition to changing the properties of the ErrorLabel, you can also set the defaultvalue for the property. If you do this, the designer will not override it and save it in the generated code, you would be able to change all the ErrorLabels from red to blue in one step, but still allow for custom color ErrorLabels.

Here's how.

When deciding whether to "Serialize" (ie generate and save code for) a property, the Form Editor does two things. First it checks the property for a DefaultValue attribute, which tells it the default value of the control. If it's value is different that the default, it saves code for the changed property. This only works for simple properties, not for colors and fonts. So there is a second way to set a default property. If it can't find DefaultValue, the Editor calls ShouldSerialize[PROPERTYNAME] on your control if it exists. If it returns true, it saves the property. False and it does not.

There is probably a block of code in Label that looks like this:

Public Overridable Overrides Function ShouldSerializeForeColor() as Boolean<br />
  Return ForeColor.Equals(SystemColors.ControlText)<br />
End Function<br />
<br />
Public Overridable Overrides Sub ResetForeColor()<br />
  ForeColor = SystemColors.ControlText<br />
End Sub


ResetForeColor is called if you press Delete on the ForeColor property in the property grid, and there's no DefaultValue to check to see what the default property is.

So ErrorLabel can have:

Public Overridable Overrides Function ShouldSerializeForeColor() as Boolean<br />
  Return ForeColor.Equals(Color.Red)<br />
End Function<br />
<br />
Public Overridable Overrides Sub ResetForeColor()<br />
  ForeColor = Color.Red<br />
End Sub


And then if we want to change our ErrorLabels to blue, we change the property grid item as described in the tutorial, and the two instances here. Recompile and our errorlabels should all be blue! AND we retain the flexibility of being able to change the color of one or two.

If it doesn't work, make sure the ForeColor property on your ErrorLabels doesn't have a bold value (which means it's serialized) which could have happened if you added ErrorLabels before it had the ShouldSerialize and Reset routines. If so, press delete on that value and it should reset back to the default color.

For an added challenge, figure out how this would work for the Font property. Wink | ;)
Generalborderstyle in a textbox Pin
moses196613-Feb-05 23:06
moses196613-Feb-05 23:06 
GeneralRe: borderstyle in a textbox Pin
Ali Zolghadri14-Feb-05 8:41
Ali Zolghadri14-Feb-05 8:41 
Generalconfig file with windows control library Pin
florida gator25-Jan-05 15:00
florida gator25-Jan-05 15:00 
GeneralRe: config file with windows control library Pin
Ali Zolghadri25-Jan-05 19:18
Ali Zolghadri25-Jan-05 19:18 
GeneralRe: config file with windows control library Pin
florida gator26-Jan-05 5:05
florida gator26-Jan-05 5:05 
GeneralRe: config file with windows control library Pin
Ali Zolghadri26-Jan-05 8:32
Ali Zolghadri26-Jan-05 8:32 
GeneralRe: config file with windows control library Pin
florida gator26-Jan-05 10:44
florida gator26-Jan-05 10:44 
GeneralRe: config file with windows control library Pin
Ali Zolghadri26-Jan-05 11:34
Ali Zolghadri26-Jan-05 11:34 

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.