Displaying Images from a folder with details in WPF
Today I decided to write how to display images from a folder with details using WPF.
What is my motivation? This StackOverflow post:
http://stackoverflow.com/questions/13034911/create-control-instance-in-wpf
Here is my full example project: ImageList.zip
The first thing I did was create a new WPF Project in Visual Studio. After that I followed these steps.
- Created an Images folder in the project and added two images.
- Changed the images properties in Visual Studio to have a Build Action of Content and to only Copy if newer.
- Created an ImageDetails object.
- Created XAML for displaying the image using binding.
- Wrote code behind to load images from a folder, get the image details, and add them to a list. Note: I had to add a reference to System.Drawing to use System.Drawing.Image.
The Model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ImageList.Model
{
public class ImageDetails
{
/// <summary>
/// A name for the image, not the file name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description for the image.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Full path such as c:\path\to\image.png
/// </summary>
public string Path { get; set; }
/// <summary>
/// The image file name such as image.png
/// </summary>
public string FileName { get; set; }
/// <summary>
/// The file name extension: bmp, gif, jpg, png, tiff, etc...
/// </summary>
public string Extension { get; set; }
/// <summary>
/// The image height
/// </summary>
public int Height { get; set; }
/// <summary>
/// The image width.
/// </summary>
public int Width { get; set; }
/// <summary>
/// The file size of the image.
/// </summary>
public long Size { get; set; }
}
}
The XAML. Basically it is an ItemsControl with an ItemsTemplate and all the complexity and binding is in the ItemsTemplate.
<Window x:Class="ImageList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid>
<ItemsControl Name="ImageList" ItemsSource="{Binding ImageList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="#FFD0D1D7" Padding="5" Margin="10,10,0,0">
<StackPanel Orientation="Horizontal">
<!--image and dimensions-->
<Grid Width="88" Height="55">
<Image Source="{Binding Path}"/>
<TextBlock Background="#B2000000" Foreground="White" Height="16" TextAlignment="Center" VerticalAlignment="Bottom">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}x{1}">
<Binding Path="Height"/>
<Binding Path="Width"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
<!--name, type and size-->
<StackPanel Orientation="Vertical" Margin="5,0,0,0" VerticalAlignment="Center">
<TextBlock Name="ImageName" Margin="1" Foreground="#FF787878" Text="{Binding FileName}"/>
<TextBlock Name="ImageType" Margin="1" Foreground="#FF787878">
<TextBlock.Text>
<MultiBinding StringFormat="Type: {0}">
<Binding Path="Extension"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock Name="ImageSize" Margin="1" Foreground="#FF787878">
<TextBlock.Text>
<MultiBinding StringFormat="Size: {0} Bytes">
<Binding Path="Size"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
The Code behind. Feel free to switch this to use MVVM if needed. I didn’t use MVVM only because this is an example only.
using ImageList.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ImageList
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string[] supportedExtensions = new[] { ".bmp", ".jpeg", ".jpg", ".png", ".tiff" };
var files = Directory.GetFiles(Path.Combine(root, "Images"), "*.*").Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower()));
List<ImageDetails> images = new List<ImageDetails>();
foreach (var file in files)
{
ImageDetails id = new ImageDetails()
{
Path = file,
FileName = Path.GetFileName(file),
Extension = Path.GetExtension(file)
};
BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.UriSource = new Uri(file, UriKind.Absolute);
img.EndInit();
id.Width = img.PixelWidth;
id.Height = img.PixelHeight;
// I couldn't find file size in BitmapImage
FileInfo fi = new FileInfo(file);
id.Size = fi.Length;
images.Add(id);
}
ImageList.ItemsSource = images;
}
}
}

It is in reality a great and useful piece of info. I aam glad that you just shared this
useful info with us. Please keep us informed like this.
Thanks for sharing.
This is great!, but what if i wanted to view the pictures horizontally not vertically ?
thanks for this awesome tutorial
Glad to be of help.