I've read multiple threads about this, but still cannot find anything that works.
I'm writing program for basically browsing database of images. I have a ListView with DataTemplate:
<DataTemplate>
<Grid Width="Auto" Height="Auto" >
<Image VerticalAlignment="Center" Source="{Binding IsAsync=True,
Converter={StaticResource Converter},
ConverterParameter={x:Static viewModel:SearchViewModel.MiniaturesHeight}}"
Grid.RowSpan="2" Stretch="None" Margin="5"
Height="{Binding Source={StaticResource Locator}, Path=MiniaturesHeight}"
Width="{Binding Source={StaticResource Locator}, Path=MiniaturesHeight}"
RenderOptions.BitmapScalingMode="NearestNeighbor" />
<TextBlock Text="{Binding Name}" Margin="5" />
</Grid>
</DataTemplate>
In converter I receive object and make URL from it's content. My problem is that I need to display 100 images per page, the whole database is for example 40k images. I would like to allow the user to click through all the pages without StackOveflowException. Unfortunately, each time I change page, memory usage increases and won't go down, even if I wait a long time.
Program itself uses around 60mb of RAM, but after changing page 5 times it's 150MB and steadily goes up.
This was my first converter:
public class ObjectToUrl : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return DependencyProperty.UnsetValue;
var obj = value as MyObject;
return "base url" + obj.prop1;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
Then I've found, that WPF is caching by default all images passed to Image control using InternetExplorer caching options. This was a problem for me, since I wanted an easy way to update image on screen when other user would change something. So I changed my converter to use the most standard technique for that to disable caching:
public class ObjectToUrl : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return DependencyProperty.UnsetValue;
var obj = value as MyObject;
var url = "base url" + obj.prop1;
try
{
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.CacheOption = BitmapCacheOption.None;
bmp.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bmp.UriSource = new Uri(url);
bmp.EndInit();
return bmp;
}
catch
{
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
This works in exactly the same way, with exception, that if I remove and add item to list bound to ListView, it loads refreshed image.
I still have problem with memory leak. Any ideas?