Home > View Post

SharedSize and the Grid

During my foibles with WPF I had often wondered how I might dynamically add new rows to a grid, inside an ItemsControl for example.

It's easy to imagine a situation where I might want to render the contents of some items in a tabular format within an ItemsControl.

Name1Value1
Name2Value2
You get the idea. You could easily achieve this through a number of nested StackPanels but you'd lose the ability to automatically line up differently sized cell contents. For example, when a value wraps or when a Name label is in a larger font size:
Name1Value
that wraps
Name2Value2
To solve this problem in WPF you'd normally just use a grid and set the attached Grid.Column and Grid.Row properties for the contents. However, as you're no doubt aware, you have to declare the number of Rows and Columns at the top of a Grid like so:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    <Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <!-- grid contents go here -->
</Grid>

But how can we make this work within an ItemsControl?

Easy.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" >
    <Page.DataContext>
        <collections:ArrayList>
            <sys:DateTime>2006-07-07</sys:DateTime>
            <sys:DateTime>2007-07-11</sys:DateTime>
            <sys:DateTime>2008-07-16</sys:DateTime>
        </collections:ArrayList>
    </Page.DataContext>

    <ItemsControl ItemsSource="{Binding}" Grid.IsSharedSizeScope='true'>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="FirstColumn" Width="Auto"/>
                        <ColumnDefinition SharedSizeGroup="SecondColumn" Width="Auto"/>
                        <ColumnDefinition SharedSizeGroup="SecondColumn" Width="Auto"/>
                    </Grid.ColumnDefinitions>

                    <TextBlock FontWeight="Bold" Text="{Binding Year}"/>
                    <TextBlock Grid.Column="1" Text="{Binding Month}"/>
                    <TextBlock Grid.Column="2" Text="{Binding Day}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Page>

Once you spot the Grid.IsSharedSizeScope attached property and SharedSizeGroup attribute on the ColumnDefinition you won't need me to explain what's going on here. Thanks to Mike Hillberg for setting me off in the right direction with this one.

Tags: WPF

 
Josh Post By Josh Twist
8:59 AM
25 May 2007

» Next Post: Windows Longhorn Server finally gets a name
« Previous Post: ClickOnce File Groups

Comments are closed for this post.

© 2005 - 2017 Josh Twist - All Rights Reserved.