Telerik blogs

Presenting data in a grid is common in many applications, but it doesn't have to look like a bunch or columns and rows.  With WPF you have freedom to make the data look totally different.  In this post, I am going to demonstrate using a custom row layout with the RadGridView for WPF.  To get started, I have setup a new window with a RadGridView.  I will be using the Northwind database Employees table for this example.  I would like to point out that if you are going to recreate this example, you will need to add the Window.Resources section in your XAML since it will not be there by default.

<Window x:Class="CardStyleRows.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation  
    Title="Window1" Height="457" Width="592" >   
 
    <Window.Resources>   
       <!-- Add this section --> 
    </Window.Resources>   
 
    <Grid> 
        <telerik:RadGridView ScrollMode="RealTime" IsReadOnly="True" Name="radGridViewCardStyleRows" ShowGroupPanel="False" ShowColumnHeaders="False" VerticalGridlinesVisibility="Hidden" AutoGenerateColumns="False" Width="500"   
                             ItemsSource="{Binding}">  
            <telerik:RadGridView.Columns> 
                <telerik:GridViewDataColumn DataType="{x:Null}"   UniqueName="EmployeeID" /> 
                <telerik:GridViewDataColumn DataType="{x:Null}"   UniqueName="LastName" /> 
                <telerik:GridViewDataColumn DataType="{x:Null}" IsSortable="False"  UniqueName="Photo"/>  
                <telerik:GridViewDataColumn DataType="{x:Null}"   UniqueName="Title"/>  
                <telerik:GridViewDataColumn DataType="{x:Null}"   UniqueName="City"/>  
                <telerik:GridViewDataColumn DataType="{x:Null}"   UniqueName="HomePhone"/>  
            </telerik:RadGridView.Columns> 
        </telerik:RadGridView> 
    </Grid> 
</Window>   
 

In a previous post, you saw me use ItemsSource to bind a List<T> to the RadGridView for WPF. This time I am going to be using a DataSet and the DataContext property.  Since I will be working with the individual columns in the XAML, DataContext will be used to tell the RadGridView where to bind the data from.  The code below demonstrates the binding operation.

var dbData = new NorthwindDataSetTableAdapters.EmployeesTableAdapter();  
radGridViewCardStyleRows.DataContext = dbData.GetData();  

A quick look at the application shows that the data is loading to the RadGridView.  Even though the Employees are all being displayed it is still a rather simple interface.  We don't even have the Employee picture being displayed yet.

  image

To make it look good, the following mockup will be used as the baseline for how we want each row to display.  We have to make a XAML representation of the layout and tell the layout what data to bind where.

image

The ControlTemplate below will perform that role by defining a layout and binding specific columns to parts of the control.  You will want to place the template inside the Windows.Resources section of the XAML.

<!-- This belongs in the Window.Resources section -->   
<ControlTemplate x:Key="MyCustomRowTemplate" TargetType="{x:Type telerik:GridViewRow}">  
    <Border Background="Transparent" Name="selectedRow" Margin="0" Opacity="1" BorderThickness="0,1,0,1" VerticalAlignment="Top" BorderBrush="#0000BBFF" HorizontalAlignment="Left">  
        <Grid  Width="400">  
            <!-- Basic layout of rows and columns --> 
            <Grid.RowDefinitions> 
                <RowDefinition Height="30"/>  
                <RowDefinition/> 
                <RowDefinition/> 
                <RowDefinition/> 
                <RowDefinition/> 
            </Grid.RowDefinitions> 
            <Grid.ColumnDefinitions> 
                <ColumnDefinition Width="35"/>  
                <ColumnDefinition Width="120"/>  
                <ColumnDefinition Width="100"/>   
                <ColumnDefinition Width="*"/>  
            </Grid.ColumnDefinitions> 
 
            <!-- Some general look and feel borders --> 
            <Border Height="Auto" HorizontalAlignment="Left" Background="#FF233052" Margin="2,1,0,0" Width="400" BorderBrush="#FFFFFFFF" CornerRadius="5,5,5,5" BorderThickness="1" Grid.ColumnSpan="4" > 
            </Border> 
            <Border Height="Auto" Grid.Row="1" HorizontalAlignment="Left" Background="#FF5E78BA" Margin="2,1,0,0" Width="400" BorderBrush="#FFFFFFFF" CornerRadius="5,5,5,5" BorderThickness="1" Grid.ColumnSpan="4" Grid.RowSpan="4" > 
            </Border>   
 
            <telerik:GridViewCell   Grid.Row="0" Grid.Column="1" Foreground="#FFFFFFFF" Width="200" Margin="0,5,0,0" HorizontalAlignment="Left" ColumnName="FirstName" TextBlock.FontSize="16"   VerticalAlignment="Center"/>   
 
            <telerik:GridViewCell   Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2" Foreground="#FFFFFFFF" Width="200" Margin="0,5,0,0" HorizontalAlignment="Left" ColumnName="Title" TextBlock.FontSize="16"   VerticalAlignment="Center"/>   
 
            <telerik:GridViewCell ColumnName="LastName" TextBlock.Foreground="#FFC4D2EF"  Grid.Row="1" Grid.Column="0" Grid.RowSpan="3"  Width="100" Margin="10,0,0,12">  
                <telerik:GridViewCell.LayoutTransform> 
                    <TransformGroup> 
                        <RotateTransform Angle="270"/>  
                    </TransformGroup> 
                </telerik:GridViewCell.LayoutTransform> 
            </telerik:GridViewCell>   
 
            <telerik:GridViewCell ColumnName="Photo" HorizontalAlignment="Center" VerticalAlignment="Center" Template="{StaticResource ImageCellTemplate}" Margin="10,50,10,20" Grid.Column="1" Grid.Row="0" Grid.RowSpan="4"/>  
 
            <Label Grid.Column="2" Foreground="#FFC4D2EF" Grid.Row="1" Content="Street Address:" /> 
            <Label Grid.Column="2" Foreground="#FFC4D2EF" Grid.Row="2" Content="City:" /> 
            <Label Grid.Column="2" Foreground="#FFC4D2EF" Grid.Row="3" Content="HomePhone:"/>  
 
            <telerik:GridViewCell  Grid.Column="3" TextBlock.Foreground="#FFFFFFFF" Grid.Row="1" ColumnName="Address">  
                <telerik:GridViewCell.Template> 
                    <ControlTemplate> 
                        <TextBlock TextWrapping="Wrap"  Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>  
                    </ControlTemplate> 
                </telerik:GridViewCell.Template> 
            </telerik:GridViewCell>   
 
            <telerik:GridViewCell TextBlock.Foreground="#FFFFFFFF"  Grid.Column="3" Grid.Row="2" ColumnName="City"/>  
 
            <telerik:GridViewCell TextBlock.Foreground="#FFFFFFFF"  Grid.Column="3" Grid.Row="3" ColumnName="HomePhone"/>  
 
            <telerik:GridViewCell  Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="4" TextBlock.Foreground="#FFFFFFFF"  ColumnName="Notes">  
                <telerik:GridViewCell.Template> 
                    <ControlTemplate> 
                        <TextBlock TextWrapping="Wrap"  Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>  
                    </ControlTemplate> 
                </telerik:GridViewCell.Template> 
            </telerik:GridViewCell> 
 
        </Grid> 
    </Border> 
</ControlTemplate> 
 

If you look through the XAML you will see that we have setup a Grid with columns and rows to create our layout.  The appropriate GridViewCells have been bound to data using the ColumnName property which will look to the DataContext property for sourcing.  The ControlTemplate below is referenced in the original template and will handle display of the Employee picture.

<!-- Place inside Window.Resources section --> 
<ControlTemplate x:Key="ImageCellTemplate" TargetType="{x:Type telerik:GridViewCell}">    
   
    <Rectangle RadiusX="5" RadiusY="5" Width="100" Height="100">     
        <Rectangle.Fill>    
            <ImageBrush x:Name="brush" ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>     
        </Rectangle.Fill>    
    </Rectangle>    
</ControlTemplate>    
 

Note that I am not binding to the ColumnName in the ImageCellTemplate because the binding took place in the original template.  Instead I set the ImageSource to the bound data of the control which will display the image.  Now that all the templates are in place it is time to apply these templates to the grid.  This next section should also be included in the Windows.Resources section of the XAML.

<!-- Place inside Window.Resources section --> 
<Style TargetType="{x:Type telerik:GridViewRow}">  
    <Setter Property="telerik:GridViewRow.Template" Value="{StaticResource MyCustomRowTemplate}"/>  
</Style>  

The XAML above is a simple style which will apply the MyCustomRowTemplate to the TargetType, in this case any GridViewRow.  Alright, we now have everything necessary to display the data in a completely new way.

image 

As you can tell, this doesn't look like a normal grid.  With custom row layouts in the RadGridView for WPF, you can enhance your interfaces quickly and easily across all your applications.  Changing the control templates above is a great way to get started learning how you can manipulate XAML to change the end result.

Download Visual Studio 2008 project: CardStyleRows.zip


Related Posts

Comments

Comments are disabled in preview mode.