Beantown .NET User Group Meeting on 11/5/2009: 4 Short Talks on Developer Utilities

Beantown .NET is going to be meeting on Thursday, 11/5/2009.  This month we’ll be doing 4 short topics about 4 different development utilities presented by Beantown members.

The talks will be:

· Nick Parker on JetBrains’ dotTrace Code Profiler
· Shaun Avery on Firebug
· Jason Haley on PowerCommands for Reflector
· Ben Day (me) on CodeRush & Refactor Pro

As always, our meeting is open to everyone so bring your friends and co-workers – better yet, bring your boss. It is not required to RSVP for our meetings but if you know you’re coming, please RSVP by 3pm on the day of the meeting to help speed your way through building security and give us an idea how much pizza to order. Click here to RSVP.

Future meetings:

- December 3 – Bill Heys, “Branching & Merging Best Practices”
- January 7 – TBA
- February 11 – Rjae Easton, “Parallelism Zen for .NET Developers”

-Ben

When: Thursday, 11/5/09, 6p – 8p

Where:
Microsoft NERD
1 Memorial Drive
Cambridge, MA

Directions: http://microsoftcambridge.com/About/Directions/tabid/89/Default.aspx

Parking: Paid parking is available in 1 Memorial Drive. 

Add a Footer Row to a Silverlight 3 DataGrid

A missing feature in the Silverlight 3 DataGrid is the ability to add a footer row.  For example, if you were trying to create a timesheet application using Silverlight, you’d want to be able to show the total number of hours for each day as shown in the image below. 

image

The solution that I came up with is slightly hack-y but definitely works.  Rather than relying on the DataGrid to provide a footer, create your own UserControl that snaps a footer row on to the bottom of the grid using a StackPanel.  

<StackPanel Orientation="Vertical">
    <data:DataGrid x:Name="m_grid"
            DataContext="{Binding Mode=OneWay}"
            ItemsSource="{Binding Weeks, Mode=TwoWay}"
            HeadersVisibility="Column" GridLinesVisibility="All"
            AutoGenerateColumns="False" LayoutUpdated="m_grid_LayoutUpdated" >
        <data:DataGrid.Columns>
            <data:DataGridTextColumn Binding="{Binding Task.Value, Mode=TwoWay}" Header="Project Name"/>
            <data:DataGridTextColumn Binding="{Binding Monday.Value, Mode=TwoWay}" Header="Monday"/>
            <data:DataGridTextColumn Binding="{Binding Tuesday.Value, Mode=TwoWay}" Header="Tuesday" />
            <data:DataGridTextColumn Binding="{Binding Wednesday.Value, Mode=TwoWay}" Header="Wednesday" />
            <data:DataGridTextColumn Binding="{Binding Thursday.Value, Mode=TwoWay}" Header="Thursday" />
            <data:DataGridTextColumn Binding="{Binding Friday.Value, Mode=TwoWay}" Header="Friday" />
            <data:DataGridTextColumn Binding="{Binding Saturday.Value, Mode=TwoWay}" Header="Saturday" />
            <data:DataGridTextColumn Binding="{Binding Sunday.Value, Mode=TwoWay}" Header="Sunday" />
            <data:DataGridTextColumn Binding="{Binding TotalHours, Mode=TwoWay}" Header="Total Hours"  />
        </data:DataGrid.Columns>
    </data:DataGrid>
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Top" x:Name="m_gridFooter">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="0" HorizontalAlignment="Left"
                 Text="Totals" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="1" HorizontalAlignment="Left"
                 Text="{Binding MondayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="2" HorizontalAlignment="Left"
                 Text="{Binding TuesdayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="3" HorizontalAlignment="Left"
                 Text="{Binding WednesdayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="4" HorizontalAlignment="Left"
                 Text="{Binding ThursdayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="5" HorizontalAlignment="Left"
                 Text="{Binding FridayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="6" HorizontalAlignment="Left"
                 Text="{Binding SaturdayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="7" HorizontalAlignment="Left"
                 Text="{Binding SundayTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
        <TextBlock VerticalAlignment="Bottom" Grid.Column="8" HorizontalAlignment="Left"
                 Text="{Binding GrandTotal, Mode=OneWay}" Padding="5,0,0,0" FontWeight="Bold"/>
    </Grid>
</StackPanel>

Ok.  So what do you do when the DataGrid’s columns get re-sized?  Basically, how do you keep the footer cells aligned and sized to match the columns in the DataGrid?  The answer is pretty easy.  Once you have the DataGrid and the supporting footer controls added to the StackPanel, you can create an event handler that attaches to the DataGrid’s LayoutUpdated event so that you can keep the footer columns.  Whenever the LayoutUpdated event fires, iterate over the columns in the DataGrid and set the corresponding footer cell control width to the same value. 

private void SyncColumnWidths(DataGrid source, Grid target)
{
    if (source == null || target == null)
    {
        return;
    }

    if (target.ColumnDefinitions.Count == source.Columns.Count)
    {
        for (int i = 0; i < target.ColumnDefinitions.Count; i++)
        {
            target.ColumnDefinitions[i].Width = new GridLength(source.Columns[i].ActualWidth);
        }
    }
}

Click here to view a running online sample.
Click here to download the source code.

-Ben

«November»
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345