Skip to main content Skip to footer

Custom Visual Styles for C1FlexGrid

What is a Control Renderer?

In the old days, controls had Font, ForeColor, and BackColor properties and that was enough to customize their appearance. When they were disabled they simply turned gray and everyone was happy. Developers did not have to worry too much about the appearance of their applications, and when they tried to customize by applying colors and fonts, the results were not always good.

But times change, and applications like Microsoft Office and the operating system itself raise the bar and user's expectations. Users started to expect colors to change when the mouse moved over an element, or when it was selected for example. And they expected gradients, transparency, and an overall sense of good and consistent design.

To address this, Windows XP introduced "themes", which consisted of canned collections of UI elements in various states (selected button, disabled scrollbar down arrow, etc). The themes can be called by any application to render common UI elements, and that works very well. But themes are very hard to customize or extend, so this solution was appealing but limited.

The next UI advance was WPF, Silverlight, XAML, and Blend. Designers can use this technology to create applications with advanced visuals and almost unlimited flexibility and extensibility. But there's a big caveat. Using Blend requires designer skills that most developers simply don't have. And it takes even talented designers a lot of time and hard work to produce really great-looking applications.

To bridge the gap between great-looking, professional styles that allow no customization, and 100% custom-made designs that take time and effort to produce, some software vendors (including Microsoft) introduced Renderers. Renderers are objects that paint each part of a control. To modify the appearance of a control completely, you simply replace the renderer with a different one (for example, the ToolStrip control ships with two standard renderers, "Professional" and "System"). This is convenient but not particularly flexible.

The flexibility comes in when you create your own renderers. You can simply create a class that derives from one of the existing renderers and customize its behavior, or you can create entirely new renderers that give you complete control over the appearance of the whole control.

Control Renderers in the C1FlexGrid

A couple of years ago, the C1FlexGrid (and most ComponentOne controls) received a new property called VisualStyle. This single property control the appearance of the entire control. If you set the VisualStyle property of any ComponentOne control to "Office2007Blue", for example, the control will automatically mimic the appearance of the Office UI, with gradients, mouse and selection tracking, etc.

Because all ComponentOne controls support the same basic visual style settings, it is easy to create applications with a professional and consistent appearance.

You can still customize the control appearance using the traditional styles, but that is usually done only to complement the standard visual style.

The VisualStyle property is implemented using internal renderers that are customized for each specific visual style. For example, the C1FlexGrid has a GridRendererOffice2007 class that provides all the functionality that is common to all office-style renderers. The Blue, Silver, and Black renderers derive from GridRendererOffice2007 and have their own color palettes (with no less than 25 colors each).

The 2010/v1 release of the C1FlexGrid exposes several renderers that you can use if you want to customize the appearance of the grid.

For example, the code below creates a renderer that is similar to the Office 2007 Blue style, except selected ranges are painted in orange instead of the default pale blue:

   var r = new C1.Win.C1FlexGrid.GridRendererOffice2007Blue();  
  r.Highlight = Color.Orange;  
  c1FlexGrid1.Renderer = r;

That is a very light customization. You can also create your own Office-style renderer class by providing a custom color palette. This is shown below:

   Color[] palette = GetCustomPalette();  
  var r = new C1.Win.C1FlexGrid.GridRendererOffice2007(palette);  
  c1FlexGrid1.Renderer = r;    

The "GetCustomPalette" method shown above is responsible for returning an array with 25 colors used to render the grid. Of course, the extra flexibility comes at a cost. Selecting 25 colors that combine well is no easy task. The next section will describe a GridRenderer class that uses this approach and provides an editor that you can use to create, edit, and save office-style renderers with custom palettes.

Finally, if simply changing the Office renderer palette is not flexible enough to fit your needs, you can create your own renderers from scratch or by extending the ones provided and overriding one or more methods in the renderer.

For example, the code below extends the GridRendererOffice2007Blue renderer to render column headers with a radial gray gradient:

   class MyRenderer : GridRendererOffice2007Blue  
  {  
    public override void OnDrawCell(C1FlexGridBase flex, OwnerDrawCellEventArgs e, C1FlexGridRenderer.CellType cellType)  
    {  
      if (cellType == CellType.ColumnHeader)  
      {  
        using (var brush = GetHeaderBrush(e.Bounds))  
        {  
          // paint the cell background  
          e.Graphics.FillRectangle(brush, e.Bounds);  

          // paint the border and content  
          e.DrawCell(DrawCellFlags.Border | DrawCellFlags.Content);  
        }  
      }  
      else  
      {  
        base.OnDrawCell(flex, e, cellType);  
      }  
    }  

    Brush GetHeaderBrush(Rectangle rc)  
    {  
      // build brush  
      using (var path = new GraphicsPath())  
      {  
        var outer = rc;  
        outer.Inflate(rc.Width / 4, rc.Height / 4);  
        path.AddEllipse(outer);  
        var pgb = new PathGradientBrush(path);  

        // apply parameters  
        pgb.CenterColor = Color.DarkGray;  
        pgb.SurroundColors = new Color[] { Color.White };  
        pgb.CenterPoint = new Point(rc.X   rc.Width / 2, rc.Y   rc.Height / 2);  

        // return the brush  
        return pgb;  
      }  
    }    

Quite a bit of code, but that is common if you want to get total rendering flexibility.

You may be wondering how this is different from using the OwnerDraw functionality that is built into the C1FlexGrid.

In this case, the code is exactly the same (which is a very good thing in case you want to reuse existing owner-draw code you may already have). The difference is this allows you to write custom renderers that are independent of the grid. You can easily attach them to existing grids, even if the grids themselves are custom classes that derive from the C1FlexGrid.

The other difference is that also expose other methods that you may override and which require less code than OnDrawCell. For example, there are methods that provide brushes and pens, and properties that determine whether the renderer should track the selection and the mouse.

The GridRenderer Component

One of the samples included with the C1FlexGrid 2010/v1 is called GridRenderer. The sample implements a component that can be added to a form to provide an extended "Renderer" property to any C1FlexGrid controls on the page.

The GridRenderer component includes an editor that can be used to customize the renderer at design or at run time.

To use the GridRenderer at design time, add a GridRenderer component to the form, then select each C1FlexGrid control on the form and set the grid's "Renderer on gridRenderer1" property to true. This "extender" property attaches the GridRenderer component to the grid. If you have many grids on the form, you can attach a single GridRenderer to all of them.

The image below shows the "Renderer" property being applied to several grids:

Next, select the GridRenderer and use the chrome on the component to select the "Edit Renderer" link.

The image below shows how to invoke the editor:

This will bring up an editor that allows you to customize the palette used to render the grid.

The image below shows the editor in action:

Select each element on the tree view and pick the colors you want to use. You can see the effect of every change immediately in the preview pane. You can save and load styles using the menu, or pick one of the predefined standard ones (Blue, Black, and Silver). If you work on a team that has a designer, he can create some great renderers and distribute them to the other members of the team.

Once you are done, click OK to close the dialog and see the new style applied to the grid on the form. You can now run the application and see your new style in action.

The FlexGrid sample GridRender can be installed with the Studio for WinForms download.

Or download the sample separately:

http://helpcentral.componentone.com/CS/.../0245.GridRenderer.zip

MESCIUS inc.

comments powered by Disqus