The problem here is not the Image control destruction. By default WPF is caching all image files and locks them. In this way when an image is displayed in multiple controls it is loaded only once in memory.
To avoid cashing you can use this kind of string to BitmapImage converter:
public class PathToBitmapConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
string filePath = (string)value;
if ( String.IsNullOrEmpty( filePath ) )
{
return null;
}
if ( !File.Exists( filePath ) )
{
return null;
}
BitmapImage bitmapImage;
try
{
using ( var fileStream = new FileStream( filePath, FileMode.Open, FileAccess.Read ) )
{
bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = fileStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();
fileStream.Close();
}
}
catch
{
bitmapImage = null;
}
return bitmapImage;
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}
In this way the image is loaded at the same time when binding is resolved and the file is no longer locked.
In other words, it seems like the user controls created by the data templates are garbage collected. The underlying problem is the way WPF handles image sources by default. By taking care of how the image is loaded yourself (which is what happens in the converter) the default behavior can be overridden. By setting CacheOption
to BitmapCacheOption.OnLoad
, "the entire image is loaded into memory at load time. All requests for image data are filled from the memory store."