Wpf Listbox Image Binding From Db


This article is written by Pon Saravanan  on 11-Feb-11 Last modified on :11-Feb-11





WPF Listbox Binding Images from DB

WPF ListBox control is quite different from windows win forms and it has lots of abilities to extend and design. With just ListBox we can design most of the equivalent controls available in ASP.Net data controls section. However the implementation of WPF ListBox is also quite different from win forms and ASP.Net controls. For e.g. binding an image is bit tricky than we do in ASP.Net and the linq and Ms SQL Sample DB northwind may demand additional knowledge on the respective technologies

Fetching Database values using Linq to SQL

As it has been already discussed in detail in the article WPF Datagrid and Linq to SQL, I am not going to detail again here. We can use the Linq to SQL to fetch the data and pass it to the WPF to bind the ListBox. The equivalent datatypes will be chose for the respective database fields. So the important mapping we need to note is the Image Datatype in SQL server. This will be mapped as System.Data.Linq.Binary. So when binding this to the Image we need to convert System.Data.Linq.Binary to the expected BitmapSource format.

Converter for Image Source

Since we need to convert the System.Data.Linq.Binary to BitmapSource, we need to specify the converter while assigning the source for the Image in the markup. This can be specified as a StaticResource. Without creating a static resource the markup does not know how to create an instance of the converter class.

Static Resources for the Converter Class

So we need to create a static resource and map the respective class file in the resources section. In the resources section under Window.Resources, we can create the static resource with a reference to the class object. This class object can be specified in the window tag as an attribute xmlns. We can specify our own namespace. In this case I named it as local and targeted to the class ImageConverter.

Image Converter class using the IValueConverter Interface

This converter has to be implementing the IValueConverter. This IValueConverter has the contract to define two methods Convert and ConvertBack.  There are some interesting facts to note here in this converter for images. I realized after few hours of struggling that I need to offset 78 bytes for images from Northwind because of the Ole Datatype. The convertback function can be returning null or can throw a not implemented exception

Screen Capture


Source Code

Markup(xaml.vb)

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfHorizontalListBox"
    Title="Window1" Height="500" Width="550" Name="Window1">
    <Window.Resources>
        <local:ImageConverter x:Key="ImageConverter"/>
        <DataTemplate  x:Key="ProductTemplate" >
            <TextBlock  Text="{Binding ProductName}"
                        FontFamily="Calibri" FontSize="14"  />           
        </DataTemplate>
        <DataTemplate  x:Key="CategoryTemplate">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top"  >
                <Border BorderThickness="1"
                            BorderBrush="silver" CornerRadius="10"
                            Padding="5" Margin="15px" Background="#E6E6E6"  >
                    <StackPanel>
                        <Image Source="{Binding Picture,
                            Converter={StaticResource ImageConverter}}"
  />
                        <ItemsControl ItemsSource="{Binding Products}"
                            ItemTemplate="{StaticResource ProductTemplate}" >
                        </ItemsControl>
                    </StackPanel>
                </Border>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox Margin="10,10,10,10" Name="lstCategories"
                 ItemTemplate="{StaticResource CategoryTemplate}" 
                 VerticalAlignment="Top">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>
</Window>

Form(xaml.Vb)

Imports System.Globalization
Imports System.IO
Class Window1
    Public  NorthwindData As New NorthwindDataContext
    Private Sub Window1_Loaded(ByVal sender As System.Object, _
                ByVal e As RoutedEventArgs) Handles MyBase.Loaded
        lstCategories.ItemsSource = NorthwindData.Categories
    End Sub
End Class

Class File(ImageConverter.VB)

Imports System.IO
Imports System.Globalization
Public Class ImageConverter
    Implements IValueConverter
    Public Function Convert(ByVal value As Object, _
                            ByVal targetType As Type, _
                            ByVal parameter As Object, _
                            ByVal culture As CultureInfo) _
                            As Object Implements IValueConverter.Convert
        Dim BmpImage As BitmapSource
        Dim BmpBytes = DirectCast(value, System.Data.Linq.Binary).ToArray
        Using BmpStream = New MemoryStream()
           
            Dim NwOffset = 78 'due to work-around to make Northwind images to work
            BmpStream.Write(BmpBytes, NwOffset, BmpBytes.Length - NwOffset)
            BmpImage = BitmapFrame.Create(BmpStream, _
                                          BitmapCreateOptions.IgnoreImageCache, _
                                          BitmapCacheOption.OnLoad)
        End Using
        Return BmpImage
    End Function
    Public Function ConvertBack(ByVal value As Object, _
                           ByVal targetType As Type, _
                           ByVal parameter As Object, _
                           ByVal culture As CultureInfo) _
                           As Object Implements IValueConverter.ConvertBack
        Return Nothing
    End Function
End Class











Comments
  • GUEST
    8/9/2011 11:10:29 PM

  • GUEST
    Succinct, clear and effective - Thanks. 11/4/2011 9:52:54 AM


Comments
   
Captcha Image
For you specially:  
Captcha Text Enter the text in the image.(Not Case sensitive)