using System.Reactive.Linq;
using System.Windows;
using Reactive.Bindings.Interactivity;
namespace DDImgDraw01.Converter;
/// <summary>
/// ドラックイベントの引数をファイルの一覧に変換するコンバーター
/// </summary>
public class DragEventArgsToFilesConverter
: ReactiveConverter<DragEventArgs?, string[]?>
{
/// <summary>
/// 変換処理
/// </summary>
/// <param name="source">ドラックイベントの引数</param>
/// <returns>ファイルのパスの一覧がセットされた文字配列</returns>
protected override IObservable<string[]?> OnConvert(IObservable<DragEventArgs?> source) => source
.Select( e =>
{
if (e is null || e.Data is null) return null;
if (e.Data.GetDataPresent(DataFormats.FileDrop) == false) return null;
var data = e.Data.GetData(DataFormats.FileDrop);
if (data is null) return null;
string[]? files = data as string[];
return files;
});
}
using System.IO;
using System.Windows.Media.Imaging;
namespace DDImgDraw01.Model;
/// <summary>
/// イメージモデル
/// </summary>
public class ImgModel
{
/// <summary>
/// ローカルファイルを読み込みBitmapImageを返す。
/// </summary>
/// <param name="file">読み込む画像ファイルのパス</param>
/// <returns>BitmapImage</returns>
public static async Task<BitmapImage> LoadFromFileAsync(string file)
{
using var fs = new FileStream(file, FileMode.Open, FileAccess.Read);
using var ms = new MemoryStream();
await fs.CopyToAsync(ms);
BitmapImage bi = await Task.Run(()=>
{
BitmapImage bi = new();
ms.Seek(0, SeekOrigin.Begin);
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = ms;
bi.EndInit();
bi.Freeze();
ms.SetLength(0);
return bi;
});
return bi;
}
}
using System.ComponentModel;
using System.Reactive.Disposables;
using System.Windows.Media.Imaging;
using DDImgDraw01.Model;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
namespace DDImgDraw01.ViewModel;
/// <summary>
/// メインウィンドウのViewModel
/// </summary>
public class MainWindowViewModel : INotifyPropertyChanged, IDisposable
{
// INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
// IDisposable
private CompositeDisposable Disposable { get; } = [];
/**************************************************************************
* プロパティ
**************************************************************************/
public ReactiveProperty<BitmapSource> PictureView { get; private set; }
public ReactiveCommand<string[]?> DropCommand { get; }
/// <summary>
/// コンストラクタ
/// </summary>
public MainWindowViewModel()
{
// INotifyPropertyChanged
PropertyChanged += (sender, e) => {};
PictureView = new ();
Disposable.Add(PictureView);
DropCommand = new ();
DropCommand.Subscribe(async files =>
{
if (files is null || files.Length == 0) return;
string file = files[0];
PictureView.Value = await ImgModel.LoadFromFileAsync(file);
}).AddTo(Disposable);
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose() => Disposable.Dispose();
}
コメント