Binding to a DataSet in XAML

At first glance binding a control (such as a ListBox) to a DataSet in XAML may not be apparent.  However all you need to remember is that the column names in a DataSet work very similar to the property names on plain CLR objects.  The trick is where you assign the DataSet to the listbox.  You can't use the ItemsSource property on a ListBox directly, because it expects an object of IEnumerable.  What you want is the DataContext.  This tells the control "Hey, I'm going to be working with this data and databinding with it."  The code below creates a simple DataSet with one table that has two columns: Name and Age, then assigns the DataSet to the DataContext of the ListBox control.

public partial class Window1 : System.Windows.Window

{

    public Window1()

    {

        InitializeComponent();

 

        this.Loaded += Window1_Loaded;

    }

 

    private void Window1_Loaded(Object sender, RoutedEventArgs e)

    {

        this.listBox.DataContext = GetData();

    }

 

    private DataSet GetData()

    {

        DataSet data = new DataSet("MyDataSet");

        DataTable table = data.Tables.Add("MyTable");

        table.Columns.Add("Name", typeof(String));

        table.Columns.Add("Age", typeof(Int32));

 

        for (int i = 0; i < 10; i++)

        {

            DataRow row = table.NewRow();

            row["Name"] = "Name " + (i + 1).ToString();

            row["Age"] = i * 10;

            table.Rows.Add(row);

        }

 

        return data;

    }

}

To be able to see your data in the ListBox you need to set a few properties in the XAML markup.  These are the ItemsSource and the ItemTemplate.  The Binding refers to the data that is currently associated to the DataContext.  So for us to bind to the data in the first table, the Path Tables[0]  is used.  Remember that using {Binding Tables[0]} and {Binding Path=Tables[0]} are synonymous.

<Window x:Class="WindowsApplication1.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="WindowsApplication1" Height="300" Width="300"

    >

 

    <Window.Resources>

 

      <DataTemplate x:Key="tableTemplate">

        <StackPanel Margin="3">

          <DockPanel LastChildFill="True">

            <TextBlock Text="Name:"

                      DockPanel.Dock="Left"

                      Margin="0,0,5,0"

                      />

            <TextBlock Text="{Binding Name}" />

          </DockPanel>

          <DockPanel LastChildFill="True">

            <TextBlock Text="Age:"

                      DockPanel.Dock="Left"

                      Margin="0,0,5,0"

                      />

            <TextBlock Text="{Binding Age}" />

          </DockPanel>

        </StackPanel>

      </DataTemplate>

 

    </Window.Resources>

 

    <Grid>

      <ListBox x:Name="listBox"

              ItemsSource="{Binding Tables[0]}"

              ItemTemplate="{StaticResource tableTemplate}"

              >

      </ListBox>

    </Grid>

 

</Window>

If we were to change the code in the load event to bind directly against the table:

private void Window1_Loaded(Object sender, RoutedEventArgs e)

{

    this.listBox.DataContext = GetData().Tables[0];

}

The markup wound just change to ItemsSource="{Binding}" because the current DataContext has the data you are looking for.  If you only need to bind to one property on a DataSet, you can remove the ItemTemplate and use DisplayMemberPath instead.  Notice that the DataTemplate used for the DataSet looks exactly the same as if we were databinding to a plain CLR object.

When you're all finished it looks like this:

Binding to a DataSet in XAML - WindowsApplication1

Hope that helps!

Published Thursday, August 23, 2007 12:11 AM by Joe
Filed under:

Comments

# re: Binding to a DataSet in XAML

Thursday, October 11, 2007 10:48 AM by Jake

Nice tutorial.  I'm new with this and was wondering how I can get the Age to be to the right instead of below the Name?

# re: Binding to a DataSet in XAML

Thursday, November 15, 2007 10:47 PM by Joe

Hey Jake,

You can do this by changing the StackPanel to a DockPanel in the DataTemplate, then setting the DockPanel.Dock to "Right" on the Age's DockPanel.

<DataTemplate x:Key="tableTemplate">

       <DockPanel Margin="3">

         <DockPanel

                DockPanel.Dock="Right"

                LastChildFill="True">

           <TextBlock Text="Age:"

                     DockPanel.Dock="Left"

                     Margin="0,0,5,0"

                     />

           <TextBlock Text="{Binding Age}" />

         </DockPanel>

         <DockPanel LastChildFill="True">

           <TextBlock Text="Name:"

                     DockPanel.Dock="Left"

                     Margin="0,0,5,0"

                     />

           <TextBlock Text="{Binding Name}" />

         </DockPanel>

       </DockPanel>

     </DataTemplate>

Powered by Community Server (Non-Commercial Edition), by Telligent Systems