Home > English > Problems customizing the layout of a DataForm using a Grid – Part III

Problems customizing the layout of a DataForm using a Grid – Part III

So let’s move on to a little more complicated scenario where we have a master detail layout all within the same DataForm. I like to embed all of my data entry layout within the same DataForm so that it can be tracked and submitted back using WCF RIA Services. We will continue to use the same object model from the last two posts.

Again we will start with our beloved Grid and perform the same layout as before with a new row underneath that will show our detail. For the detail, I am just creating a TabControl with a single TabItem and a DataGrid bound to the same object model collection.

<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    xmlns:l="clr-namespace:SilverlightApplication2.Models"
    >
    <UserControl.Resources>
		<DataTemplate x:Key="DataFormGridTemplate">
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="Auto" />
					<ColumnDefinition Width="Auto" />
				</Grid.ColumnDefinitions>
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="*"/>
				</Grid.RowDefinitions>
				<toolkit:DataField Label="First Name" Grid.Column="0" Grid.Row="0">
					<TextBox Text="{Binding FirstName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Last Name" Grid.Column="0" Grid.Row="1">
					<TextBox Text="{Binding LastName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Business Name" Grid.Column="1" Grid.Row="0">
					<TextBox Text="{Binding BusinessName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Bio of Business" Grid.Column="1" Grid.Row="1">
					<TextBox Text="{Binding BusinessBio, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Fax" Grid.Column="0" Grid.Row="2">
					<TextBox Text="{Binding Fax, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Phone" Grid.Column="1" Grid.Row="2">
					<TextBox Text="{Binding Phone, Mode=TwoWay}" />
				</toolkit:DataField>

                		<sdk:TabControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">
                    			<sdk:TabControl.Items>
                        			<sdk:TabItem Header="Test 1">
                            				<sdk:DataGrid MinHeight="200" 
								HorizontalAlignment="Left" 
								VerticalAlignment="Top">
                                				<sdk:DataGrid.ItemsSource>
                                    					<l:Customers />
                                				</sdk:DataGrid.ItemsSource>
                            				</sdk:DataGrid>
			                        </sdk:TabItem>
		                    </sdk:TabControl.Items>
                		</sdk:TabControl>
			</Grid>
		</DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <toolkit:DataForm Header="Data Entry Sample"
			AutoGenerateFields="False"
			ReadOnlyTemplate="{StaticResource DataFormGridTemplate}"
			EditTemplate="{StaticResource DataFormGridTemplate}"
            >
            <toolkit:DataForm.ItemsSource>
                <l:Customers />
            </toolkit:DataForm.ItemsSource>
        </toolkit:DataForm>
	</Grid>
</UserControl>

When we render this DataTemplate, you will notice that the space between the two columns has stretched out to accommodate the width of the DataGrid. We will come back to this:

DataForm using a Grid with Master Detail layout

Now let’s look at how what the template would like for the StackPanel:

<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    xmlns:l="clr-namespace:SilverlightApplication2.Models"
    >
    <UserControl.Resources>
        <DataTemplate x:Key="DataFormStackPanelTemplate">
			<StackPanel>
				<StackPanel Orientation="Horizontal">
					<StackPanel toolkit:DataField.IsFieldGroup="True">
						<toolkit:DataField Label="First Name">
							<TextBox Text="{Binding FirstName, Mode=TwoWay}" />
						</toolkit:DataField>
						<toolkit:DataField Label="Last Name">
							<TextBox Text="{Binding LastName, Mode=TwoWay}" />
						</toolkit:DataField>
						<toolkit:DataField Label="Fax">
							<TextBox Text="{Binding Fax, Mode=TwoWay}" />
						</toolkit:DataField>
					</StackPanel>
					<StackPanel toolkit:DataField.IsFieldGroup="True">
						<toolkit:DataField Label="Business Name">
							<TextBox Text="{Binding BusinessName, Mode=TwoWay}" />
						</toolkit:DataField>
						<toolkit:DataField Label="Bio of Business">
							<TextBox Text="{Binding BusinessBio, Mode=TwoWay}" />
						</toolkit:DataField>
						<toolkit:DataField Label="Phone">
							<TextBox Text="{Binding Phone, Mode=TwoWay}" />
						</toolkit:DataField>
					</StackPanel>
				</StackPanel>
				<StackPanel toolkit:DataField.IsFieldGroup="True">
					<sdk:TabControl>
						<sdk:TabControl.Items>
							<sdk:TabItem Header="Test 1">
								<sdk:DataGrid MinHeight="200" HorizontalAlignment="Left" VerticalAlignment="Top">
									<sdk:DataGrid.ItemsSource>
										<l:Customers />
									</sdk:DataGrid.ItemsSource>
								</sdk:DataGrid>
							</sdk:TabItem>
						</sdk:TabControl.Items>
					</sdk:TabControl>
				</StackPanel>
			</StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <toolkit:DataForm Header="Data Entry Sample"
			AutoGenerateFields="False"
			ReadOnlyTemplate="{StaticResource DataFormStackPanelTemplate}"
			EditTemplate="{StaticResource DataFormStackPanelTemplate}"
			>
            <toolkit:DataForm.ItemsSource>
                <l:Customers />
            </toolkit:DataForm.ItemsSource>
        </toolkit:DataForm>
	</Grid>
</UserControl>

When we render this out, we get the what we would expect in the layout:

DataForm using a StackPanel with Master Detail layout

So what am missing in the Grid template? The problem is that I have only defined two Column definitions with their value set to “Auto”. All we need to do is add another Column definition with its width set to “*”. The following Grid template shows how to remedy this issue:

<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
    xmlns:l="clr-namespace:SilverlightApplication2.Models"
    >
    <UserControl.Resources>
		<DataTemplate x:Key="DataFormGridTemplate">
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="Auto" />
					<ColumnDefinition Width="Auto" />
					<ColumnDefinition Width="*" />
				</Grid.ColumnDefinitions>
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="*"/>
				</Grid.RowDefinitions>
				<toolkit:DataField Label="First Name" Grid.Column="0" Grid.Row="0">
					<TextBox Text="{Binding FirstName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Last Name" Grid.Column="0" Grid.Row="1">
					<TextBox Text="{Binding LastName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Business Name" Grid.Column="1" Grid.Row="0">
					<TextBox Text="{Binding BusinessName, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Bio of Business" Grid.Column="1" Grid.Row="1">
					<TextBox Text="{Binding BusinessBio, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Fax" Grid.Column="0" Grid.Row="2">
					<TextBox Text="{Binding Fax, Mode=TwoWay}" />
				</toolkit:DataField>
				<toolkit:DataField Label="Phone" Grid.Column="1" Grid.Row="2">
					<TextBox Text="{Binding Phone, Mode=TwoWay}" />
				</toolkit:DataField>

                		<sdk:TabControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3">
                    			<sdk:TabControl.Items>
                        			<sdk:TabItem Header="Test 1">
                            				<sdk:DataGrid MinHeight="200" 
								HorizontalAlignment="Left" 
								VerticalAlignment="Top">
                                				<sdk:DataGrid.ItemsSource>
                                    					<l:Customers />
                                				</sdk:DataGrid.ItemsSource>
                            				</sdk:DataGrid>
			                        </sdk:TabItem>
		                    </sdk:TabControl.Items>
                		</sdk:TabControl>
			</Grid>
		</DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <toolkit:DataForm Header="Data Entry Sample"
			AutoGenerateFields="False"
			ReadOnlyTemplate="{StaticResource DataFormGridTemplate}"
			EditTemplate="{StaticResource DataFormGridTemplate}"
            >
            <toolkit:DataForm.ItemsSource>
                <l:Customers />
            </toolkit:DataForm.ItemsSource>
        </toolkit:DataForm>
	</Grid>
</UserControl>

So I added a new Column definition and I also updated the ColumnSpan of the TabControl from “2” to “3”. That it! Let’s take a look at what the output would be:

DataForm using a Grid with Master Detail adjusted layout

So hopefully you can see some of the areas that you need to be aware of when you start making your layout a little advanced.

Note: It is worth noting that the StackPanel approach with the IsFieldGroup attribute is better in my opinion because it will also constrain your TabStop of your controls to follow the contraints of the group and then move to another. I have found that if I get my Grid layout mixed up, that my TabStops go crazy. This is easy to fix but I find that the grouping is sometimes easier.

Hope this helps…

Advertisements
  1. September 1, 2011 at 10:50 am

    It is excellent post. I was also facing this type problem.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: