なべひろBlog

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

MVVMなWPFアプリケーションでドラッグ&ドロップをしてみる

まあ、検索すれば幾つかヒットするネタではありますが、ドンピシャでヒットしなかったので検証してみます。

構成は.NET Core3.1なWPFアプリでPrismとReactivePropertyを使っています。

やっている事はImageにドラッグ&ドロップされたJPGファイルを表示するだけです。

XAMLファイルに記述するImage
<Image AllowDrop="True" Source="{Binding ViewImage.Value}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewDragOver">
            <ri:EventToReactiveCommand Command="{Binding PreviewDragOverCommand}"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="Drop">
            <ri:EventToReactiveCommand Command="{Binding DropCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Image>

表示するSourceはViewImageをBindingします。

PreviewDragOverイベントにはPreviewDragOverCommand、DropイベントにはDropCommandが割り当てられます。

ViewModel
// 表示するイメージのファイル名
public ReactivePropertySlim ViewImage { get; } = new ReactivePropertySlim();
// ImageのPreviewDragOverイベントのコマンド
public ReactiveCommand PreviewDragOverCommand { get; } = new ReactiveCommand();
// Imageのイベントのコマンド
public ReactiveCommand DropCommand { get; } = new ReactiveCommand();

が対応します。

ボタンクリックなどのコマンドなどとは違いイベントのコマンドは

ReactiveCommand

となる事に注意してください。

コンストラクタ
ViewImage.Value = @"\Image_DragAndDrop;component\Resource\blank.jpg";
PreviewDragOverCommand.Subscribe(ImagePreviewDragOver).AddTo(Disposable);
DropCommand.Subscribe(ImageDrop).AddTo(Disposable);

上記の1行目ですが、ドラッグ&ドロップするImageのSourceに何もないとドラッグ&ドロップできないので仮のJPGファイルを最初にソースとして設定しておきます。

イベント処理
// ImageのPreviewDragOverイベントに対する処理
private void ImagePreviewDragOver(DragEventArgs e)
{
    // マウスカーソルをコピーにする。
    e.Effects = DragDropEffects.Copy;
    // ドラッグされてきたものがFileDrop形式の場合だけ、このイベントを処理済みにする。
    e.Handled = e.Data.GetDataPresent(DataFormats.FileDrop);
}

// ImageのDropイベントに対する処理
private void ImageDrop(DragEventArgs e)
{
    // ドロップされたものがFileDrop形式の場合は、各ファイルのパス文字列を文字列配列に格納する。
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
    // 複数ドロップの可能性もあるので、今回は最初のファイルを選択して表示
    ViewImage.Value = files[0];
}

「ImageDrop」メソッドの「files」にドラッグ&ドロップされたフルパスを含むファイル名が来ます。

配列を使用しているのは複数のファイルをドラッグ&ドロップされた時の対処です。

特に難しい事はないので他のコントロールの応用も簡単かと思います。

Prism関連記事

MVVMなWPFアプリケーションでバーコードリーダーの情報をキャッチする。

PrismのIDialogServiceを試してみる

Prismを使ったWPFアプリケーションで多重起動を抑制する

Prism使ったWPFでLivetCask.Messagingを使ってみる

Prismで複数のページを持ったアプリを作ってみる

PrismのUserControlを動的に配置する