пятница, 30 сентября 2011 г.

Как в WPF приложении отобразить иконку файла

Некоторое время назад передо мной возникла задача отобразить в приложении иконку файла. Быстро было найдено решение – использовать функцию CreateBitmapSourceFromHIcon. Однако в рамках паттерна MVVM непосредственное использование функции было неудобно. Простенький конвертер, преобразующий путь к файлу в его иконку, делает удобным размещение иконки файла непосредственно в XAML.

Сам конвертер выглядит очень просто:

public class FileIconExtractConverter : IValueConverter
{
//Собственно извлечение иконки для файла
private static ImageSource IconForFile(string filePath)
{
if (!System.IO.File.Exists(filePath))
return null;

using (System.Drawing.Icon sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath))
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
sysicon.Handle,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(16, 16));
}
}

//реализация интерфейста IValueConverter
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return IconForFile((value ?? String.Empty).ToString());
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}

#endregion
}





И также просто выглядит его использование в шаблоне данных, который может быть использован, например для элементов списка:




<DataTemplate x:Key="AttachmentDisplayTemplate">
<DataTemplate.Resources>
<core:FileIconExtractConverter x:Key="FileIconExtractConverter" />
</DataTemplate.Resources>
<Grid x:Name="grid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- иконка файла -->
<Image
Source="{Binding, Converter={StaticResource FileIconExtractConverter}}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="2,2,0,2" SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="LowQuality"
Width="16" Height="16"/>

<!-- путь к файлу -->
<TextBlock x:Name="FilePath" MaxHeight="48" Margin="25,0,0,0"
VerticalAlignment="Center" HorizontalAlignment="Left"
Background="{x:Null}"
Text="{Binding }" />
</Grid>
</DataTemplate>





Этот конвертер использовался для отображения иконок файлов, прикрепленных к проекту в программе для анализа проектных данных ProjectsProfiler, правда там использовался более сложный шаблон.

Результат выглядит вот так:



image



P.S. Уже после того, как я реализовал и использовал описанный выше конвертер, я наткнулся на аналогичное решение на CodeProject.com. Это решение более продвинутое, позволяет управлять размером получаемой иконки и даже извлекать Thumbnail большого размера.

4 комментария:

  1. Ответы
    1. Есть, конечно :)
      А что именно нужно?

      Удалить
    2. нужно добавить в проект класс FileIconExtractConverter.
      После этого его можно использовать в любой форме. Сначала подключить его как ресурс





      А потом ссылаться на этот ресурс при указании конвертера
      Source="{Binding, Converter={StaticResource FileIconExtractConverter}}"

      Удалить