Welcome to MSDN Blogs Sign in | Join | Help
Windows Presentation Foundation (Avalon) Databinding to objects

Databinding to an object datasource is really simple in Windows Presentation Foundation. I didn't find any good samples around, so I'm posting some code here to help you save some time.

My scenarion is really simple, I would like to create an WPF application to visualize my DVD collection. The code also shows how to bind an Image control i WPF to an JPEG image stored inside the SQL Server database (not just a pointer to a file). The code is simplified to only illustrate the main concepts and I have not worked with the design part yet.

First I start with a class to represent the information about a DVD title:

    public class Dvd
    {

        int _dvdId;
        private string _title;
        private byte[] _frontCover;

        public int Id { get { return _dvdId; } }

        public string Title { get { return _title; } }

        public BitmapFrame FrontCover
        {
            get
            {
                BitmapFrame frontCover = System.Windows.Media.Imaging.BitmapFrame.Create(new System.IO.MemoryStream(_frontCover));

                return frontCover;
            }
        }


        public Dvd(
            int id,
            string title,
            byte[] frontCover)
        {
            _dvdId = id;
            _title = title;
            _frontCover = frontCover;
        }

    }

 

The Data Access Layer contains a method to return a list DVD's from the database:

        public static List<Dvd> GetTitles()
        {
            OdbcConnection connection = new OdbcConnection(m_connectionString);

            string selectCommand = @"
                SELECT     DvdId, Title, FrontCover
                FROM         Titles";

            OdbcCommand command = new OdbcCommand(selectCommand, connection);

            List<Dvd> titles = new List<Dvd>();

            connection.Open();
            OdbcDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                Dvd dvd = new Dvd(
                    Convert.ToInt32(reader["DvdId"]),
                    Convert.ToString(reader["Title"]),
                    (byte[])reader["FrontCover"]);

                titles.Add(dvd);

            }

            return titles;
        }

 

Then we have the DvdCollection class which includes a method to return a list of Dvd objects:

using System;
using System.Collections.Generic;
using System.Text;
using DvdLibrary.BusinessEntities;
using DvdLibrary.DataAccessLayer;

namespace DvdLibrary.BusinessLogicLayer
{
    public class DvdCollection
    {
        public static List<Dvd> GetTitles()
        {
            return TitlesDAL.GetTitles();
        }

    }
}

Then in the XAML code-behind, I have this code to retrieve a a list of DVD titles from the business logic layer:

private void OnInit(object sender, EventArgs e)
{
    List<Dvd> titles = DvdCollection.GetTitles();

    DvdList.DataContext = titles;
}

Finally we have the XAML file showing how to do the Databind to the list of DVD titles using a ListBox:

<?Mapping XmlNamespace="DvdLibrary_BusinessLogicLayer" ClrNamespace="DvdLibrary.BusinessLogicLayer" Assembly="DvdLibrary"?>
<Grid
 xmlns="
http://schemas.microsoft.com/winfx/avalon/2005"
 xmlns:x="
http://schemas.microsoft.com/winfx/xaml/2005"
 xmlns:c="
http://schemas.microsoft.com/winfx/markup-compatibility/2005"
 xmlns:d="
http://schemas.microsoft.com/expression/interactivedesigner/2005"
 c:Ignorable="d"
 Background="#FFFFFFFF"
 x:Name="DocumentRoot"
 Width="640"
 Height="480"
 x:Class="DvdBrowser.Scene1"
 Loaded="OnInit"
 >

 <Grid.Resources>
  <ResourceDictionary>
   <Storyboard x:Key="OnLoaded" FillBehavior="HoldEnd" BeginTime="{x:Null}" />

   <DataTemplate x:Key="DvdItemTemplate">
    <Grid>
     <Image Source="{Binding FrontCover}"></Image>
     <TextBlock Text="{Binding Title}"
       FontWeight="Bold" />
    </Grid>
   </DataTemplate>
   
  </ResourceDictionary>
 </Grid.Resources>

 <Grid.Triggers>
  <EventTrigger RoutedEvent="FrameworkElement.Loaded">
   <EventTrigger.Actions>
    <BeginStoryboard x:Name="OnLoaded_BeginStoryboard" Storyboard="{DynamicResource OnLoaded}"/>
   </EventTrigger.Actions>
  </EventTrigger>
 </Grid.Triggers>
 
 <ColumnDefinition/>
 <RowDefinition/>
 <ListBox
  IsSynchronizedWithCurrentItem="True"
  x:Name="DvdList"
  Margin="19,23,41,16"
  Width="Auto"
  Height="Auto"
  RenderTransformOrigin="0.5,0.5"
  ItemsSource="{Binding}"
  ItemTemplate="{StaticResource DvdItemTemplate}"
  />
</Grid>

Posted: Friday, September 30, 2005 8:44 PM by olavt

Comments

RWlodarczyk said:

More ideally any property returning an implementation of a BitmapSource, such as:
public BitmapFrame FrontCover
the return type should be BitmapSource instead of the specific implementation of BitmapSource. This just provides a more general usage scenario.
# October 2, 2005 12:30 PM
Anonymous comments are disabled
Page view tracker