mostlylucid

STATIC ARCHIVE of mostlylucid.co.uk of old
posts - 897, comments - 685, trackbacks - 11

My Links

News

Archives

Post Categories

Misc. Coding

GridView with no Inline Styles (mostly!)

UPDATE: I’ve put the entire CSS Manager source including this control on my Codeplex site, you can get it here.

This has been a bit of an obsession for the past couple of days…I wrote previously about a little CSS combining control which I’m working on. As part of this I wanted to experiment with ways of optimizing our current controls.

Well, I thought I’d throw this up (in both meanings of the term) here for some quick reference. Again, not fully implemented, just an experiment. You’ll also quickly notice that there’s some other gubbins missing; like my CSSManager base page, I’ll update this post with their location once I get them tidied up a bit.

Well, what do I do to avoid inline styles, simple…cheat :). Firstly I went spelunking in the GridView control using Reflector and saw where the styles are actually set. A method called ‘PrepareControlHierarchy’, this basically sets the style properties on all  of GridView’s child controls. The ‘other’ way you can do this is through the use of Control Adapters (e.g., the CSS Friendly Adapters), but they’re a bit more involved than I wanted for this.
In this method I basically call ‘Reset()’ on the styles and set ‘CSSClass’ for each of the styles instead.
For the actual styles, I pull them into a string and throw them over to my little Page control for addition to my CSS Manager thingy…(again, be online soon). This then renders the style out to either page or an external CSS file.

Anyway, as I’ve said this is really just a hack but it was a fun little thing to play with…and who knows, someone might find it useful!

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Web.UI.WebControls;
   6:  using System.Web.UI;
   7:  using System.Drawing;
   8:  using System.IO;
   9:   
  10:  namespace CSSManager
  11:  {
  12:      public class CSSGridView : GridView
  13:      {
  14:   
  15:          public new CSSManagerPage Page
  16:          {
  17:              get
  18:              {
  19:                  return (CSSManagerPage)base.Page;
  20:              }
  21:          }
  22:   
  23:          protected override void OnPreRender(EventArgs e)
  24:          {
  25:   
  26:              if (!DesignMode)
  27:              {
  28:                  StringBuilder sb = new StringBuilder();
  29:                  if (this.Controls.Count > 0)
  30:                  {
  31:                      bool controlStyleCreated = base.ControlStyleCreated;
  32:                      Table table = this.Controls[0] as Table;
  33:   
  34:   
  35:   
  36:                      if (table == null)
  37:                          throw new Exception("The first control must be a Table");
  38:   
  39:   
  40:   
  41:                      Style baseStyle = base.ControlStyle;
  42:                      string baseStyleName = this.ClientID + "BaseStyle";
  43:                      sb.AppendFormat(".{0}{{{1}}}", baseStyleName, baseStyle.GetStyleAttributes(this).Value);
  44:   
  45:                      table.ControlStyle.Reset();
  46:                      table.ControlStyle.CssClass = baseStyleName;
  47:   
  48:                      Style alternatingRowStyle = AlternatingRowStyle;
  49:                      alternatingRowStyle.MergeWith(RowStyle);
  50:                      sb.AppendFormat(".{0}{{{1}}}", this.ClientID + "AlternatingRow", alternatingRowStyle.GetStyleAttributes(this).Value);
  51:                      sb.AppendFormat(".{0}{{{1}}}", this.ClientID + "Row", RowStyle.GetStyleAttributes(this).Value);
  52:   
  53:                      foreach (GridViewRow row in this.Rows)
  54:                      {
  55:   
  56:                          switch (row.RowType)
  57:                          {
  58:                              case DataControlRowType.Header:
  59:                                  if (this.ShowHeader && (this.HeaderStyle != null))
  60:                                  {
  61:                                      string className = this.ClientID + "HeadStyle";
  62:   
  63:                                      sb.AppendFormat(".{0}{{{1}}}", className, HeaderStyle.GetStyleAttributes(this).Value);
  64:                                      row.ControlStyle.Reset();
  65:                                      row.CssClass = className;
  66:                                  }
  67:                                  break;
  68:   
  69:   
  70:                              case DataControlRowType.Footer:
  71:                                  if (this.ShowFooter && (this.FooterStyle != null))
  72:                                  {
  73:                                      string className = this.ClientID + "FootStyle";
  74:                                      sb.AppendFormat(".{0}{{{1}}}", className, FooterStyle.GetStyleAttributes(this).Value);
  75:                                      row.ControlStyle.Reset();
  76:                                      row.CssClass = className;
  77:                                  }
  78:                                  break;
  79:   
  80:   
  81:                              case DataControlRowType.DataRow:
  82:                                  string rowClassName = string.Empty;
  83:                                  if ((row.RowIndex % 2) == 0)
  84:                                  {
  85:                                      rowClassName = this.ClientID + "AlternatingRow";
  86:   
  87:                                  }
  88:                                  else
  89:                                  {
  90:                                      rowClassName = this.ClientID + "Row";
  91:                                  }
  92:                                  row.ControlStyle.Reset();
  93:                                  row.CssClass = rowClassName;
  94:                                  break;
  95:   
  96:                          }
  97:   
  98:                      }
  99:                  }
 100:                  this.Page.RegisterCSSStyle(sb.ToString());
 101:              }
 102:              base.OnPreRender(e);
 103:          }
 104:   
 105:   
 106:   
 107:          protected override void PrepareControlHierarchy()
 108:          {
 109:              if (DesignMode)
 110:                  base.PrepareControlHierarchy();
 111:          }
 112:   
 113:      }
 114:  }

What does this actually generate? Well, if you’ve seen the output you normally get from a GroidView you’ll be familiar with all of the inline styles (so, style=”font-family…” etc…which are duplicated for every single row…which kind of sucks as they’re almost all exactly the same. This little control instead generates a little bit of CSS.

   1:  <style type="text/css">
   2:      .GridView1BaseStyle{background-color:White;border-color:#CCCCCC;border-width:1px;border-style:None;font-family:Verdana;}.GridView1AlternatingRow{color:#000066;}.GridView1Row{color:#000066;}
   3:  </style>

Then hooks that up to the GridView:

   1:  <table class="GridView1BaseStyle" border="0" id="GridView1">
   2:          <tr>
   3:              <th scope="col">Discontinued</th><th scope="col">ProductID</th><th scope="col">ProductName</th><th scope="col">QuantityPerUnit</th><th scope="col">ReorderLevel</th><th scope="col">UnitPrice</th><th scope="col">UnitsInStock</th><th scope="col">UnitsOnOrder</th><th scope="col">Categories.CategoryID</th><th scope="col">Suppliers.SupplierID</th>
   4:          </tr><tr class="GridView1AlternatingRow">
   5:              <td><span disabled="disabled"><input id="GridView1_ctl02_ctl00" type="checkbox" name="GridView1$ctl02$ctl00" disabled="disabled" /></span></td><td>1</td><td>Chai</td><td>10 boxes x 20 bags</td><td>10</td><td>18.0000</td><td>39</td><td>0</td><td>1</td><td>1</td>
   6:          </tr>…

So you see that we (mostly) got rid of all of the inline styles; apart from the annoying “border=0” which is a major pain in the ass to clear out! In ASP.NET 4 you’ll be able to turn this off as well though!

Oh, one important thing. This also works with Auto-Formatting…and the designer :)

Print | posted on Friday, May 08, 2009 11:48 PM | Filed Under [ ASP.NET Code Snippets ]

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 4 and 1 and type the answer here:

Powered by: