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="https://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="https://schemas.microsoft.com/winfx/xaml/2005"
xmlns:c="https://schemas.microsoft.com/winfx/markup-compatibility/2005"
xmlns:d="https://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>
Comments
- Anonymous
October 02, 2005
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.