Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#

The New WPF GridView Customized - 1 of 3

Rate me:
Please Sign up or sign in to vote.
4.84/5 (54 votes)
20 Jun 2007CPOL5 min read 296.1K   117   40
Customizing the WPF GridView and Binding multiple sources
Screenshot - DC_12.png

Abstract

This article explains how to get data from many sources and add them to a gridview (WPF), create the gridview and later customize it in a WPF application.

Index

  • Introduction
  • Prerequisites
  • Creating the Gridview
  • XML Databinding
    • Remember XML and .NET 2.0
    • XML Binding using only XAML
    • XML Binding using XAML and C#
  • SQL Server Binding
  • Access Binding
  • MySql Binding
  • Customizing the Gridview
    • Customize the header
    • Customize the background
    • Customize the rows

Introduction

The gridview is one of the possibilities to show a listview. You can customize it in many ways. At the moment, there's little information and its customization is not very well implemented in Blend yet (you can't design it without viewing XAML code). Another thing is that in Blend, you can bind XML data but what happens with the rest of datasources. How I don't see any way in XAML. I show how to bind to XAML from C#.

Prerequisites

To proceed with the article, you will need the following software:

  • Visual Studio 2005 C# (Or Express C# Orcas)
  • WPF Extensions for VS2005 (included in Orcas)
  • Framework 3.0
  • Microsoft Expression Blend
  • SQL Server 2005 Express (optional)
  • Microsoft Access 2003 or higher (optional)
  • MySql Server (optional)

Creating the Gridview

First of all create a new project, type project C# NET Framework 3.0: Window Application (WPF).

Now add a ListView (not a ListBox), from "All Controls" section in toolbox, and change the Name to "DataList". You will have code like:

XML
<Window x:Class="sample1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="sample1" Height="320" Width="500"
    >
    <Grid>
    <ListView Margin="0,0,0,50" Name="DataList" />
  </Grid>
</Window>

Take a look at the Window.g.cs code. If it is added, the internal DataList will be ok, if not add the next line:

C#
internal System.Windows.Controls.ListView DataList;

You don't need to initialize it because it exists in the XAML section. Run the project to be sure all is working.

XML Databinding

Here I explain in the code explanation how to bind from XML using only XAML (static version) and then from XML with XAML and C# (my favourite way) because it is easier to change the source at runtime.

I will use in this section the next one called "data.xml" file:

XML
 <Customers>
  <Customer>
 <Code>1234</Code>
 <Name>EPI</Name>
 <Country>Sesame Street</Country>
  </Customer>
  <Customer>
 <Code>3234</Code>
 <Name>Paul</Name>
 <Country>United Kingdom</Country>
  </Customer>
 <Customer>
 <Code>3344</Code>
 <Name>Juan</Name>
 <Country>Spain</Country>
  </Customer>
 <Customer>
 <Code>4321</Code>
 <Name>Dodo</Name>
 <Country>Mars</Country>
  </Customer>
</Customers>

Remember XML and .NET 2.0

To bind XML data to a DataGridView in .NET 2.0, you have to add the following code:

C#
string file = "data.xml";
DataSet ds = new DataSet("Table");
ds.ReadXml(file);
dG1.DataSource = ds.Tables[0].DefaultView;

You will now have a fast way to show data:

Screenshot - DC_1.png

XML Binding Using Only XAML

In this case, first you have to create a new Window.Resource:

XML
<Window.Resources>
    <XmlDataProvider x:Key="CustomersDS" Source="C:\data.xml"/>
</Window.Resources>

and now we have to change the listview to have a gridview aspect:

XML
<ListView Margin="0,0,0,50" ItemTemplate="{DynamicResource CustomerTemplate}" 
 ItemsSource="{Binding Source={StaticResource CustomersDS}, XPath=/Customers/Customer}">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Code" DisplayMemberBinding="{Binding XPath=Code}"/>
          <GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=Name}"/>
          <GridViewColumn Header="Country" 
		DisplayMemberBinding="{Binding XPath=Country}"/>
        </GridView>
      </ListView.View>
</ListView>

With this method, you will have a static XML binding using only XAML:

Screenshot - DC_2.png

XML Binding Using XAML and C#

Generate the "data.xml" shown before, and (that's the way I like code), create the method OnLoad. To do that, add the "Loaded" event to the XAML <window> tag:

XML
<Window x:Class="WindowsApplication7.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ...
    Loaded="OnLoad"
>

And in the window1.xaml.cs, add the namespace using System.Data; and the method:

C#
public void OnLoad(Object o, EventArgs e)
{
            string file = @"c:\data.xml";
            DataSet ds = new DataSet("Table");
            ds.ReadXml(file);
            List1.DataContext = ds.Tables[0].DefaultView;
}

Now you have to assign the link between "Table" and "BindingPath" in the XAML with the following code:

XML
<Grid x:Name="LayoutRoot">
    <ListView Name="List1" Margin="35,34,212,123" 
	ItemTemplate="{DynamicResource CustomerTemplate}" 
	ItemsSource="{Binding Path=Table}">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="Code" DisplayMemberBinding="{Binding Path=Code}"/>
          <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
          <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Path=Country}"/>
        </GridView>
      </ListView.View>
    </ListView>
</Grid>

To understand better the link between XAML and C#, take a look at this diagram:

Screenshot - DC_3.png

Loaded calls OnLoad that fills the table and paints on gridview. I like this method because you can easily change the datasource.

SQL Server Binding

Create a new database call "Customers" and create inside the table "customers" with this structure:

Screenshot - DC_4.png

We add example data in the table:

Screenshot - DC_5.png

Remember that the user must have a role to access this database and activate datareader and datawriter:

Screenshot - DC_6.png

Now add the namespace: using System.Data.SqlClient; and the modify the previous OnLoad method to have:

C#
public void OnLoad(Object o, EventArgs e)
{
    string s_command = "SELECT Code,Name,Country FROM customers";
    SqlConnection connection = new SqlConnection();
    SqlDataAdapter adapter = new SqlDataAdapter();
    SqlCommand command = new SqlCommand();
    command.CommandText = s_command;
    adapter.SelectCommand = command;
    connection.ConnectionString = "Data Source=192.168.10.9,1433;
	Initial Catalog=Customers;Network Library=DBMSSOCN;
	User ID=temporalguest;Password='';";
    command.Connection = connection;
    DataSet ds = new DataSet();
    adapter.Fill(ds,"Table");
    List1.DataContext = ds.Tables[0].DefaultView;
    connection.Close();
} 

NOTE: The SQL queries are not case sensitive, the XAML are CASE SENSITIVE so, the name of the columns have to be the same as the name of DisplayMemberBinding.

Access DataBinding

Open Access and create a new database called "customers.mdb" and add inside the table "customers" like the previous section.

Add the namespace using System.Data.OleDb; and simply modify the OnLoad method to the next:

C#
public void OnLoad(Object o, EventArgs e)
{
   string s_command = "SELECT Code,Name,Country FROM customers";
   OleDbConnection connection = new OleDbConnection();
   OleDbDataAdapter adapter = new OleDbDataAdapter();
   OleDbCommand command = new OleDbCommand();
   command.CommandText = s_command;
   adapter.SelectCommand = command;
   connection.ConnectionString = 
	@"Provider=Microsoft.Jet.OLEDB.4.0;Data source=C:\customers.mdb";
   connection.Open();
   command.Connection = connection;
   DataSet ds = new DataSet();
   adapter.Fill(ds);
   List1.DataContext = ds.Tables[0].DefaultView;
   connection.Close();
}

MySql Databinding

Requisites to have a successful compilation:

Screenshot - DC_7.png

Taking care that we have correctly installed MySQLServer, simply add the namespace using MySql.Data.MySqlClient and change the OnLoad method to:

C#
public void OnLoad(Object o, EventArgs e)
{
  string s_command = "SELECT Code,Name,Country FROM customers";
  MySqlConnection connection = new MySqlConnection();
  MySqlCommand command = new MySqlCommand();
  MySqlDataAdapter adapter = new MySqlDataAdapter();
  command.CommandText = s_command;
  adapter.SelectCommand = command;
  connection.ConnectionString = "Server=192.168.10.9;
	Database=Customers;User Id=temporalguest;Password=111111;";
  command.Connection = connection;
  DataSet ds = new DataSet();
  adapter.Fill(ds, "Table");
  List1.DataContext = ds.Tables[0].DefaultView;
  connection.Close();
}

Customizing the GridView

In this article, I show how to customize the main aspects of the gridview. This is a strange control in WPF because it is not accessible from Blend in design time, so here I explain how to customize it in XAML code.

Customize the Header

If you want to customize the header of every column, add the following code in the Listview tag:

XML
<GridView ColumnHeaderTemplate="{StaticResource BlueHeader}">

In case you want to customize per column, add the following code:

XML
<GridViewColumn Header="Code" DisplayMemberBinding="{Binding Path=Code}" 
	HeaderTemplate="{StaticResource BlueHeader}" />

Now simply add the resource in the <Window> tag:

XML
<Window.Resources>
    <DataTemplate x:Key="BlueHeader">
      <StackPanel Orientation="Horizontal" Margin="-5,-5,-5,-5" Width="120">
        <StackPanel.Background>
          <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FF223B84" Offset="1"/>
            <GradientStop Color="#FF57A0F4" Offset="0.5"/>
            <GradientStop Color="#FF4B94EC" Offset="0.5"/>
          </LinearGradientBrush>
        </StackPanel.Background>
        <TextBlock Margin="10,10,10,10" Text="{Binding}" 
		VerticalAlignment="Center"  Foreground="White"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

Now we will have a gridview like:

Screenshot - DC_9.png

Customize the Background

That's too easy, you can do it in Blend if you want. The code you need to add in the <ListView> tag is:

XML
<ListView.Background>
        <LinearGradientBrush EndPoint="0.939,0.919" StartPoint="0.061,0.081">
          <GradientStop Color="#FFFFE07E" Offset="0"/>
          <GradientStop Color="#FFFFFAEA" Offset="1"/>
        </LinearGradientBrush>
</ListView.Background>

And then we will have:

Screenshot - DC_10.png

Customize the Rows

First let's change the typical style of the rows. To do that, simply add the next XAML code in the <ListView> tag:

XML
<ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}"  >
          <Setter Property="Height" Value="24" />
          <Setter Property="Background" Value="#5EF4E057" />
          <Setter Property="Foreground" Value="#FF4B94EC"/>
        </Style>
</ListView.ItemContainerStyle>

Now add XAML code to change when the mouse is over. To do that, add an XAML style trigger, with the typical mouse over code you will have:

XML
<ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}"  >
          <Setter Property="Height" Value="24" />
          <Setter Property="Background" Value="#5EF4E057" />
          <Setter Property="Foreground" Value="#FF4B94EC"/>
          
          <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="true">
              <Setter Property="Foreground" Value="DarkBlue" />
              <Setter Property="Background">
                <Setter.Value>
                  <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFFFC704" Offset="0.986"/>
                    <GradientStop Color="#FFF4E057" Offset="0.5"/>
                    <GradientStop Color="#FFF4E057" Offset="0.51"/>
                  </LinearGradientBrush>
                </Setter.Value>
              </Setter>
            </Trigger>
            
          </Style.Triggers>
        </Style>
</ListView.ItemContainerStyle>

And finally, you will have a well styled gridview that was really hardcoded in previous versions of .NET:

Screenshot - DC_12.png

In the Next Chapter...

I will explain:

  • Adding data from an ArrayList
  • Grouping data in the gridview
  • More style customization
  • Editing data of the gridview
  • Adding controls to the gridview

Release History

  • 1.0 Original version of the article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Expediteapps
Spain Spain
I'm Electronic Engineer, I did my end degree project at Astrophysical Institute and Tech Institute. I'm HP Procurve AIS and ASE ,Microsoft 3.5 MCTS
I live in Canary Islands ,developing customized solutions

Deeply involved in Xamarin Forms LOB (including Azure Cloud with offline support, custom controls, dependencies) projects, WP8.1 & W10 projects, WPF modern styled projects. Portable libraries like portablePDF, portableOneDrive, portableReports and portablePrinting (using Google Printing API).


Web and apps showcase at:
Expediteapps


Take a look to my blog
Blog

Comments and Discussions

 
QuestionThanks Pin
Kashif Ahmad Khan21-Oct-15 21:27
Kashif Ahmad Khan21-Oct-15 21:27 
QuestionNice Article Pin
MAYURI2012111-Jul-12 18:54
MAYURI2012111-Jul-12 18:54 
AnswerRe: Nice Article Pin
Juan Pablo G.C.11-Jul-12 20:33
Juan Pablo G.C.11-Jul-12 20:33 
QuestionSpanish? Pin
AspDotNetDev7-Sep-09 20:24
protectorAspDotNetDev7-Sep-09 20:24 
QuestionHow to code selected row event in grid view please reply becos i am new to wpf. Pin
Member 356401922-Jun-09 2:24
Member 356401922-Jun-09 2:24 
QuestionWPF GridView code sample Pin
Joezer BH17-Jun-09 22:41
professionalJoezer BH17-Jun-09 22:41 
AnswerRe: WPF GridView code sample Pin
jinal shah22-Jun-09 23:25
jinal shah22-Jun-09 23:25 
<Window x:Class="WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="385.679" Width="528.955" ResizeMode="CanResize" WindowState="Maximized"
Loaded="Window_Loaded">
<Grid>
<ListView Name="List1" GridViewColumnHeader.Click="GridViewColumnHeader_Click" ItemTemplate="{DynamicResource CustomerTemplate}" ItemsSource="{Binding Path=Table}" Margin="22.491,58.31,37.485,149.107">
<ListView.View>
<GridView >
<GridViewColumn DisplayMemberBinding="{Binding CustomerId}" Header="Id" />
<GridViewColumn DisplayMemberBinding="{Binding FirstName}" Header="First Name" />
<GridViewColumn DisplayMemberBinding="{Binding LastName}" Header="Last Name" />
<GridViewColumn DisplayMemberBinding="{Binding Phone}" Header="Phone" />
<GridViewColumn Header="Action">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Grid.Column="5" HorizontalAlignment="Right" Padding="2"
Tag="{Binding Path=CustomerId}" Click="cmdView_Clicked">View ...</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>


</GridViewColumn>

</GridView>
</ListView.View>
</ListView>

<TextBox Margin="106,371,8,0" Text="{Binding Path=FirstName}" TextWrapping="Wrap" x:Name="txtFirstName" Height="20" VerticalAlignment="Top" />
<Label HorizontalAlignment="Left" Margin="24,369,0,0" Width="78" Content="First Name" x:Name="lblFirstName" Height="22" VerticalAlignment="Top" />
<TextBox Margin="106,399,8,0" x:Name="txtLastName" TextWrapping="Wrap" Text="{Binding Path=LastName}" VerticalAlignment="Top" Height="24"/>
<Label HorizontalAlignment="Left" Margin="24,397,0,0" x:Name="lblLastName" Width="78" Content="Last Name" Height="26" VerticalAlignment="Top"/>
<TextBox Margin="106,430,8,0" x:Name="txtPhone" VerticalAlignment="Top" Height="26" Text="{Binding Path=Phone}" TextWrapping="Wrap"/>
<Label HorizontalAlignment="Left" Margin="24,430,0,0" x:Name="lblPhone" VerticalAlignment="Top" Width="78" Height="26" Content="Phone"/>
<Button HorizontalAlignment="Left" Margin="33,311,0,0" VerticalAlignment="Top" Width="94" Height="32" Content="Add New" x:Name="btnAddNew"/>
<Button Margin="0,311,59,0" x:Name="btnDelete" VerticalAlignment="Top" Height="32" Content="Delete" Width="94" HorizontalAlignment="Right"/>


</Grid>

</Window>
Questionhow to sort name alphabetical order Pin
priyanka_raj5-Mar-09 18:45
priyanka_raj5-Mar-09 18:45 
Generalwhere is the link to second part and third Pin
Chaitanya Kolla9-Feb-09 20:40
Chaitanya Kolla9-Feb-09 20:40 
QuestionAsk for help Pin
dearcyrix18-Sep-08 4:54
dearcyrix18-Sep-08 4:54 
GeneralSet other Background than default Blue when a ListViewItem is selected Pin
pixel3cs10-May-08 5:36
pixel3cs10-May-08 5:36 
QuestionTotal Row? Pin
Dan Hunt25-Oct-07 9:33
Dan Hunt25-Oct-07 9:33 
GeneralPlease post the next thread Pin
Sanoj T18-Oct-07 20:21
Sanoj T18-Oct-07 20:21 
Generalalignment and columns width Pin
webspeed15-Oct-07 6:22
webspeed15-Oct-07 6:22 
GeneralHere is my new one Juan Pin
Sacha Barber25-Jul-07 10:03
Sacha Barber25-Jul-07 10:03 
GeneralXAML How to get parent property Pin
Juan Pablo G.C.15-Jul-07 23:19
Juan Pablo G.C.15-Jul-07 23:19 
GeneralRe: XAML How to get parent property Pin
Sacha Barber23-Jul-07 20:40
Sacha Barber23-Jul-07 20:40 
QuestionWhat happens when Pin
Sacha Barber12-Jul-07 7:00
Sacha Barber12-Jul-07 7:00 
AnswerRe: What happens when Pin
Juan Pablo G.C.12-Jul-07 23:18
Juan Pablo G.C.12-Jul-07 23:18 
GeneralRe: What happens when Pin
Sacha Barber12-Jul-07 23:26
Sacha Barber12-Jul-07 23:26 
GeneralI have just solved (without the trigger matters) Pin
Juan Pablo G.C.13-Jul-07 1:37
Juan Pablo G.C.13-Jul-07 1:37 
GeneralRe: I have just solved (WITH the trigger matters) Pin
Juan Pablo G.C.13-Jul-07 2:59
Juan Pablo G.C.13-Jul-07 2:59 
GeneralRe: I have just solved (WITH the trigger matters) and header text color Pin
Juan Pablo G.C.13-Jul-07 3:43
Juan Pablo G.C.13-Jul-07 3:43 
GeneralRe: I have just solved (WITH the trigger matters) and header text color Pin
Sacha Barber13-Jul-07 5:18
Sacha Barber13-Jul-07 5:18 
GeneralRe: I have just solved (WITH the trigger matters) and header text color Pin
Juan Pablo G.C.15-Jul-07 22:08
Juan Pablo G.C.15-Jul-07 22:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.