なべひろBlog

プログラミングをメインに仕事に関するアレコレを発信しています。

WPFアプリのImageにファイルを掴ませないようにする

前回MVVMなWPFアプリでImageにドラッグ&ドロップをやる手段を書きましたが、あの方法には困った問題が1つあります。

それは表示していた(している)ファイルをアプリケーションが掴んでいるのでファイルの削除ができません。

表示されてなければそのうち離してくれるかもしれませんが、悠長に待っている訳にはいきません。

じゃあどうするかと言えばWriteableBitmapに変換して変換したデータを表示するようにすればファイルは掴みません。

また、Viewは変更不要です。

ViewModelでBindingするのは

public ReactivePropertySlim ViewImage { get; } = new ReactivePropertySlim();

stringがWriteableBitmapに変わってます。

そして実際に画像を表示するには

// 対象がリソース
System.Windows.Resources.StreamResourceInfo sr = Application.GetResourceStream(new Uri(@"\Image_DragAndDrop;component\Resource\blank.jpg", UriKind.Relative));
BitmapFrame bf = BitmapFrame.Create(sr.Stream);
ViewImage.Value = new WriteableBitmap(bf);

// 対象がファイル
MemoryStream data = new MemoryStream(File.ReadAllBytes("フルパスのファイル名"));
ViewImage.Value = new WriteableBitmap(BitmapFrame.Create(data));
data.Close();

対象が内部リソースなら気にする事はありませんが、外部ファイルの場合MemoryStreamのCloseメソッドを実行する事で取得した画像ファイルを手放します。


2020/2/28追記

もう少しスマートに書く例を掲載します。

これを

// 対象がファイル
MemoryStream data = new MemoryStream(File.ReadAllBytes("フルパスのファイル名"));
ViewImage.Value = new WriteableBitmap(BitmapFrame.Create(data));
data.Close();

こうできます。

// 対象がファイル
using MemoryStream data = new MemoryStream(File.ReadAllBytes("フルパスのファイル名"));
ViewImage.Value = new WriteableBitmap(BitmapFrame.Create(data));

常日頃忘れないようにしたいusingですね。