Welcome to WindowsClient.net | My Blog | Sign in | Join

Faisal's Blog

February 2008 - Posts

Creating ImageListBox in WPF

In Windows Presentation Foundation Images can be added as ListBox items and this is one of the coolest features of WPF to me.But i never thought that this can be done so easily.To do this i created two classes Photo and PhotoList.Let's walk through the Code.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Collections.Specialized;
using System.Windows.Controls;


namespace ImageViewer
{
    public class Photo
    {
        private String _path;
        public String Path { get { return _path; } }
        private Uri _uri;
        public Uri Uri { get { return _uri; } }
        private BitmapFrame _image;
        public BitmapFrame Image { get { return _image; } }

        public Photo(string path)
        {
            _path = path;
            _uri = new Uri(_path);
            _image = BitmapFrame.Create(_uri);
        }

        public override string ToString()
        {
            return Path;
        }
    }
}

After Creating this class i've created another Class named PhotoList which inherits from ObservableCollection<T> class which is a built-in implementation of collection class that provides INotificationCollectionChanged interface.In a Data Binding scenario when data is collection of objects this class is quite usefull.For example when we use ItemsControl such as ListBox,ListView , TreeView etc. to display collection of records.When we want to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically,we can implement the INotificationCollectionChanged  interface.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Collections.Specialized;
using System.Windows.Controls;

namespace ImageViewer
{

    public class PhotoList : ObservableCollection<Photo>
    {
        DirectoryInfo _directory;

        public PhotoList()
        {
        }

        public PhotoList(string path) : this(new DirectoryInfo(path)) { }

        public PhotoList(DirectoryInfo directory)
        {
            _directory = directory;
            Update();
        }

        private void Update()
        {
            foreach (FileInfo f in _directory.GetFiles("*.jpg"))
            {
                Add(new Photo(f.FullName));
            }
        }

        public string Path
        {
            set
            {
                _directory = new DirectoryInfo(value);
                Update();
            }
            get { return _directory.FullName; }
        }

        public DirectoryInfo Directory
        {
            set
            {
                _directory = value;
                Update();
            }
            get { return _directory; }
        }

    }
}

Here's my XAML :

<Window x:Class="ImageViewer.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ph="clr-namespace:ImageViewer"
    Title="Window1" Height="480" Width="640">
    
    <Window.Resources>
        <ph:PhotoList x:Key="MyPhotos" 
        Path="D:\Visual Studio Projects\WPF APPLICATIONS\ImageViewer\ImageViewer\Images">
      </ph:PhotoList>

    </Window.Resources>
    
    <Grid>
        <ListBox Margin="9,11,0,14" Name="listBox1" ItemsSource="{Binding Source={StaticResource MyPhotos}}" HorizontalAlignment="Left" Width="124" SelectionChanged="listBox1_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding Path}"></Image>
                </DataTemplate>

            </ListBox.ItemTemplate>
        </ListBox>
        <Image Height="417" Margin="155,0,12,14" Name="img" Stretch="Fill" VerticalAlignment="Bottom" />
    </Grid>
</Window>

To qualify namespace i used this :

xmlns:ph="clr-namespace:ImageViewer"

Under the <Window.Resource> tag i used Photolist and assign it's Path property to the exact path where my images are located.Look at the x:Key attribute which uses to uniquely identify elements that are created and referenced as resources.

That's what i tried here x:Key="MyPhotos" .Next I have created ListBox and assign it's Margin,Name and ItemsSource property which usually gets or sets a collection used to generate the content of  the items control.I assinged  MyPhotos which i created as resource previously.

ItemsSource="{Binding Source={StaticResource MyPhotos}}"  this syntax assigns the photolist class as ListBox's ItemsSource.To display the items as images i used an image control under the ListBox's DataTemplate tags and set it's Source Property to {Binding Path}  and the job was done.I found all the ListBox items as images instead of traditional text.

Here is my Image ListBox :

ImageListBox

Now all we need is select an image item in the ImageListBox and see the Image in the Image control right to the ImageListBox.Here's my SelectionChanged event handling code to wire SelectionChanged event.

private void listBox1_SelectionChanged(Object sender, SelectionChangedEventArgs args)
       {
           ListBox List = ((ListBox)sender);
           if (List != null)
           {
               int index = List.SelectedIndex;
               if (index >= 0)
               {
                   string selection = listBox1.SelectedItem.ToString();
                   if ((selection != null) && (selection.Length != 0))
                   {
                       Uri selLoc = new Uri(selection);
                       BitmapImage id = new BitmapImage(selLoc);
                       img.Source = id;
                   }
               }
              
           }
       }

After wiring this event and running my application i found something like this :

ImageListBox2

 

 

Any comments or suggestion would be highly appreciated.Happy coding.

kick it on DotNetKicks.com Add to Technorati Favorites
Posted: Feb 14 2008, 02:11 AM by ilves | with no comments |
Filed under:
Thanks to WindowsClient.Net

I wanna give thanks to windowsclient.net team for giving me the opputunity to be a part of windowsclient community.

I'll try to the best of my ability to share my thoughts here.

Page view counter