WPF イメージリソースを画面表示するために、BitmapをBitmapSourceに変換する
[WPF Tips]
1.状況
プロジェクトプロパティのリソース(Resource.resx)に画像を登録しておいて、
登録した画像のビルドアクションプロパティをResourceにしておく
と、XAMLで画像を以下のように指定できる。
<Button Command="{Binding OnShowSearchDialog}" CommandParameter="{Binding SelectedSearchCondtion}" Width="26" ToolTip="検索条件を指定しデータを取得します"> <Image Source="Resources/ic_cloud_download_black_36dp.png" /> </Button>
ただ、このアイコンを動的に変更使用とすると一手間必要。
上記リソースに登録すると、コード上から、リテラルではなく、Properties.Resource.{リソース名} で参照でき補完も効くし、変更するとコンパイルエラーとなるので非常に便利なので、ViewModelにてプロパティを公開し、バインドしたい。
ちなみに、System.Drawing.Bitmap 型となる。
このViewModelのプロパティをバインドしてもうまくいかない。
using System.Drawing; private Bitmap _IconImageSource; public Bitmap IconImageSource { get { return _IconImageSource; } set { _IconImageSource = value; RaisePropertyChanged(); } } : IconImageSource = Properties.Resources.ic_help_outline_black_18dp;
2.対応
BitmapをBitmapSourceに変換するコンバーターを作成し、それを利用する。
3.参考
4.サンプル
4.1 コンバーター
public class WinFormBitmapConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var bitmap = value as Bitmap; if (bitmap == null) { return null; } try { using (var memoryStream = new MemoryStream()) { // You need to specify the image format to fill the stream. // I'm assuming it is PNG bitmap.Save(memoryStream, ImageFormat.Png); memoryStream.Seek(0, SeekOrigin.Begin); return CreateBitmapSourceFromBitmap(memoryStream); } } catch (Exception) { return null; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } private static BitmapSource CreateBitmapSourceFromBitmap(Stream stream) { var bitmapDecoder = BitmapDecoder.Create( stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); // This will disconnect the stream from the image completely... var writable = new WriteableBitmap(bitmapDecoder.Frames.Single()); writable.Freeze(); return writable; } }
4.2 Xamlでの利用
<Window x:Class="Shikalog.View.ProgressDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Shikalog.View" xmlns:converter="clr-namespace:Shikalog.Common.Converter" mc:Ignorable="d"> <Window.Resources> <converter:WinFormBitmapConverter x:Key="BitmapConverter"/> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <Image Grid.Row="0" Grid.Column="0" Source="{Binding IconImageSource, Converter={StaticResource BitmapConverter}, Mode=OneWay}" Width="24"/> <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Message}" TextWrapping="Wrap" /> </Grid> </Window>
以上