Silverlight UI Rant #1 – DataGrid Last Column Fill

If you’ve used the the Silverlight 2 DataGrid, you’ve no doubt seen this:

silverlightDatagrid01

I really hate when this happens!  I’ve seen several forum discussions where folks were looking to get rid of this nastiness, so I know I’m not the only one losing sleep over it.  I haven’t come across a solution in anything I’ve seen and so now that I have one, I thought I’d share it.

I ran into this a few weeks back and tried most of the obvious things with defining the DataGridColumns myself rather than auto-generating them.  In these defined DataGridColumns, I tried setting the Width of the last column to "*" just like you would a standard Grid.ColumnDefinition if you wanted to have it take up the remainder of the space.  This did nothing more than invite my buddy, AG_E_PARSER_BAD_PROPERTY, to show up…again.  It appears that star-sizing isn’t yet implemented for DataGridColumn derivatives.

This morning I was finally able to grab a few minutes to dive into DataGrid and find out what I could do about this.  I decided to create an ExtendedDataGrid and add a LastColumnFill DependencyProperty similar to way the DockPanel has a LastChildFill. Most of the work is happening in this method which is called if the LastColumnFill is true:

  1. private void AdjustLastColumnWidth(Size finalSize)
  2. {
  3.     // get the Vertical ScrollBar
  4.     ScrollBar scrollBar = this.GetTemplateChild("VerticalScrollbar") as ScrollBar;
  5.  
  6.     // compute the width to allow for the scrollbar based on it's visibility.
  7.     double scrollBarWidthAllowance =
  8.         (scrollBar != null && scrollBar.Visibility == Visibility.Visible) ?
  9.         scrollBar.ActualWidth + 2 : 2;
  10.  
  11.     // compute the width of all the columns excluding the last one
  12.     var widthOfAllButLastColumn =
  13.         Columns.TakeWhile(c => c != Columns.Last() && c.Visibility == Visibility.Visible)
  14.         .Sum(c => c.ActualWidth);
  15.  
  16.     // set the last column width    
  17.     Columns.Last().Width = new DataGridLength(finalSize.Width
  18.         - widthOfAllButLastColumn – scrollBarWidthAllowance);
  19.  
  20. }

This is the result:

silverlightDatagrid02

Much better!  The live demo shows it with and without a vertical scrollbar.  Note that it also handles
auto-generated DataGridColumns if that’s your thang.

Here’s the live demo.

Here’s the code.

This entry was posted in Silverlight, Silverlight 2, UI and Usability, UI Rant. Bookmark the permalink.

Comments are closed.