Angled Column Headers with Silverlight 2’s DataGrid

Posted on August 10, 2008 by Matt Berseth.
Categories: Contributors, Silverlight.

At the software shop I work at screen real-estate is always at a premium.bread and butter of our business is data, and the more of it we can fit on a screen the happier our customers are. Sometimes, to cram more data into our grids, we end up abbreviating column headers, wrapping them or possibly combining 2 or 3 data elements into a single cell. Usually this works out O.K., but sometimes we still run out of room. When this happens we either remove columns, or break the grid across separate pages.

Honestly, usually none of this is a huge problem.there is that certain class of data that just doesn't fit well into an HTML TABLE - when the length of the data elements are substantially smaller than the data label's.grid ends up looking too sparse.

I hadn't thought of this before, but football statistics fit into this category pretty well (I noticed this while leafing through Sports Illustrated Fantasy Football Preview).football season is short (only 16 games) and the per game statistics that are worth counting have relatively small values (i.e, carries, receptions, touchdowns, etc...). Sports Illustrated angled the column headers to keep the grid from running off the page and I thought it looked pretty good.

So where is this going? Well, I haven't had a chance to play with the new Silverlight 2 Beta 2 bits so I thought it might be interesting see what it would take to override Silverlight's DataGrid to render the column headers at a 45 degree angles. I should warn you that I am *very* new to Silverlight, but I thought this was interesting enough to write up a quick post about.

Live Demo | Download

image

Binding Data to the Grid

I bound the DataGrid to a collection of WideReciever objects (anyone else excited about football being just around the corner?). It all feels a lot like working with ASP.NET's GridView. I just want the grid to render text, so I have bound the properties of the WideReciever objects to the DataGridTextColumn. Then I set the column header text using the Header property and then used the ElementStyle attribute to set the padding on the text that is rendered.

Here is the XAML for the DataGrid.


    
		
			
				
					
						
						
						
					
				
			
		
		
		
		
		
		
		
		
	

And here is the style setting I am using to set the padding and alignment of the cell text.

Determining the DataItemIndex

I didn't find a way to bind the current rows index to the grid. So to work around this I wired the Loaded event of a TextBlock to run a bit of code that looks up the bound WideReciever index and populates the TextBlock with this value.

private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
	// get a reference to the TextBlock
    TextBlock textBlock = (TextBlock)sender;
    
	// get the data item index
	index = ((IList)this.grid.ItemsSource).IndexOf((WideReciever)textBlock.DataContext);

	// set the index
	textBlock.Text = index + 1 < 10 ? string.Format("{0}.  ", index + 1) : string.Format("{0}.", index + 1);
}

Styling the Column Headers

Finally, to get the column headers to render at an angle, I overrode the Template for the DataGrid's DataGridColumnHeaders and used a plain old Canvas to position the header text how I wanted it. To get the text to rotate I used the RotateTransform and set the angle property to -35.

That's it. Enjoy!

no comments yet.

Leave a comment

Names and email addresses are required (email addresses aren't displayed), url's are optional.

Comments may contain the following xhtml tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>