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>
以上
