C#のWinFormでD&Dを使い画像ファイルの受け渡し

C# コンピュータ
C#

エクスプローラーなどから画像ファイルをアプリへドラックアンドドロップで画像を表示。
表示されている画像を別アプリへドラックアンドドロップすることが出来る。
ちなみにエクスプローラーのフォルダへドラックアンドドロップするとファイルが移動する。
(effectが影響?要調査)
GIMPへドラックアンドドロップするとファイルが開かれます。

プロジェクトの作成

.NET CLI

dotnet.exe new winforms -n <プロジェクト名>
cd <プロジェクト名>

ソースコード

ファイル名:Form1.cs

using Microsoft.Win32;

namespace GraphicBoard03;

public partial class Form1 : Form
{
   // パネル
    Panel Panel1 = new()
    {
        Dock = DockStyle.Fill,  // クライアント領域一杯に広げる
        AutoScroll = true,  // スクロールバー
        AllowDrop = true, // D&D有効
    };
    // ピクチャボックス
    PictureBox PictureBox1 = new()
    {
        SizeMode = PictureBoxSizeMode.AutoSize, // 自動サイズ
    };
    // 画像ファイルのパス
    string ImageFilePath = "";

    public Form1()
    {
        InitializeComponent();

        // コントロールの登録
        Panel1.Controls.Add(PictureBox1);
        this.Controls.Add(Panel1);

        // ピクチャボックス・マウスダウンイベント
        this.PictureBox1.MouseDown += ( sender, e ) => PictureBox1_MouseDown( sender, e );
        // パネルドラックエンターイベント
        this.Panel1.DragEnter += ( sender, e ) => Panel1_DragEnter( sender, e );
        // パネルドラックドロップイベント
        this.Panel1.DragDrop += ( sender, e ) => Panel1_DragDropAsync( sender, e );
    }

    // ピクチャボックス・マウスダウンイベント
    void PictureBox1_MouseDown( object? sender, MouseEventArgs e )
    {
        /*********************************************************
        * 画像を他アプリへD&D
        *********************************************************/

        // イメージオブジェクトがセットされていない場合何もしないで返る
        if ( PictureBox1.Image is null || ImageFilePath == "" ) return;
        // 押されたマウスのボタンが左でない場合も何もしないで返る
        if (e.Button != MouseButtons.Left) return;

        var effect = DragDropEffects.Copy | DragDropEffects.Move;
        string[] files = {ImageFilePath};
        var data = new DataObject(DataFormats.FileDrop, files);

        // ドラックアンドドロップ実行
        var result = PictureBox1.DoDragDrop(data, effect);
        if ( result == DragDropEffects.None)
        {
            MessageBox.Show(string.Format("{0} D&D 失敗", ImageFilePath));
        }
    }

    // パネルドラックエンター
    void Panel1_DragEnter(object? sender, DragEventArgs e)
    {
        if (e.Data is null) return;
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }

    // パネルドラックドロップイベント
    async void Panel1_DragDropAsync(object? sender, DragEventArgs e)
    {
        /*********************************************************
        * 他アプリからD&Dで画像を取得
        *********************************************************/

        if (e.Data is null) return;
        var data = e.Data.GetData(DataFormats.FileDrop, false);
        if (data is not string[] files) return;
        ImageFilePath = files[0];

        var task = Task.Run(()=>        
        {
            using var fs = new FileStream(ImageFilePath, FileMode.Open, FileAccess.Read);
            return new Bitmap(fs);
        });
        PictureBox1.Image?.Dispose();
        PictureBox1.Image = await task;
    }

}

コメント