I am trying to extract icon in another thread with IMultiValueConverter and even though this works in another project it does not work here. IsAsync=True makes start the converter without FullPath value, and IsAsync=False blocks the UI especially when extracting icons from .lnk files.
<Image>
<Image.Source>
<MultiBinding Converter="{StaticResource Fullpath2Icon}" >
<MultiBinding.Bindings>
<Binding RelativeSource="{RelativeSource Self}" />
<Binding Path="FullPath" IsAsync="True" />
</MultiBinding.Bindings>
</MultiBinding>
</Image.Source>
</Image>
public class Fullpath2IconConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
System.Windows.Controls.Image image = values[0] as System.Windows.Controls.Image;
if (values[1] == null) return null;
string mypath = values[1] as string;
ThreadPool.QueueUserWorkItem((WaitCallback)delegate
{
image.Dispatcher.Invoke(DispatcherPriority.Normal,
(ThreadStart)delegate {
image.Source = System.Drawing.Icon.ExtractAssociatedIcon(mypath).IconToImageSource();
Can you explain me the reason for this or suggest any way of improving this?
EDIT: I created a class extending image and now it looks like this:
<local:cIconImage Path="{Binding FullPath}"></local:cIconImage>
public class cIconImage : System.Windows.Controls.Image
{
public cIconImage()
{
//this.Loaded += new RoutedEventHandler(cIconImage_Loaded);
Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
{
Source = GetImage();
}));
}
It is much better as now the list populates, and each icon appears as it is being extracted, but during some long .lnk extraction UI still locks up.
Setting the Image control's Source property inside the Convert method doesn't make any sense. Not to mention calling Dispatcher.Invoke immediately in a separate thread.
Use a simple binding on the Source property like this:
and a single value converter that simply returns the result of the conversion:
Update: In order to asynchronously load a number of icon images, you should bind to an
ObservableCollection<ImageSource>
in your view model (without a converter) and fill that collection from a background thread. Note that the images are created in the background thread and must therefore be frozen.