📦

ドラッグ&ドロップでサーバにファイルを渡す (MudBlazor)

に公開

はじめに

この記事は、以下を下敷きにしています。

https://zenn.dev/tetr4lab/articles/5b875f53d04e3a

前提

  • .NET 8.0
  • MudBlazor 8.9.0

やりたいこと

画像をアップロードする際に、ドラッグ・アンド・ドロップできるといいですね。

サーバからダウンロードする場合は以下をどうぞ。
https://zenn.dev/tetr4lab/articles/d69583796163b4

実装

ドラッグ非対応

比較のため、非対応版も掲げておきます。

https://github.com/tetr4lab/Prices/blob/3ccab93e4ffd5f0476a071099ec4786d2efa3e11/Prices/Prices/Components/Pages/ProductList.razor#L84-L94

実のところ、ActivatorContentに配置されているボタンをアイコンとテキストに置き換えても、ファイル選択ボタン(<input hidden="" type="file" ~>)がクリックに応答して、ファイルピッカーが開きます。
ただし、このファイル選択ボタンはhiddenのため、ドラッグ&ドロップには応答しません。

ドラッグ対応

同じMudFileUploadを使用しますが、若干、使い方が異なります。

Hidden="@false"とした上で、FilesChangedからOnFilesChangedへ切り替えることで、ドラッグ&ドロップを受け取れるようになります。
また、@ondrop@ondragenter@ondragleave@ondragendを利用すると、マウスオーバーに対してリアクションさせることができます。

https://mudblazor.com/components/fileupload#drag-and-drop-example

以下は、上記のサンプルから大きくは変わっていません。

https://github.com/tetr4lab/Prices/blob/da82eaf5d8df62468ead9da306a1f32ab077501b/Prices/Prices/Components/Pages/ProductList.razor#L84-L97

https://github.com/tetr4lab/Prices/blob/da82eaf5d8df62468ead9da306a1f32ab077501b/Prices/Prices/Components/Pages/ProductList.razor#L216-L235
複数ファイルを選択させる場合は、サンプル通りに、型変数をIReadOnlyList<T> にして、AppendMultipleFilesを指定します。

機序と留意点

Hidden="@false"にしたことで、ファイル選択ボタン(<input hidden="" type="file" ~>)からhiddenが外れ、代わりにopacity: 0;によって不可視化されています。
そして、この「見えないけれど実体化したファイル選択ボタン」は、InputClassへの設定で、子要素を覆うように広げられています。
その結果、領域全体で、ドラッグ&ドロップを含む「ファイル選択ボタンの本来の機能」を享受できるようになります。
InputStyleopacity: 0.4; background-color: #FCC;とかにすることで、その様子を確認できます。

子要素とファイル選択ボタンは親子でなく兄弟なので、何かの拍子に範囲がずれてしまうことがあります。
例えば、親要素でセンタリングしようと(この例なら<td align="center">)すると、てきめんにズレます。
挙動がおかしい場合は、先の「ボタンを可視化する」ハックで、状況を把握しやすくなります。

なお、title=""は、ファイル選択ボタンのツールチップが表示されないようにするものです。

おまけ

サンプルコードの全体は、以下のリポジトリにあります。

https://github.com/tetr4lab/Prices

https://github.com/tetr4lab/Tetr4labNugetPackages

画像表示

画像のURLを割り当てたくなかったので、data:として直に埋め込んでいます。

https://github.com/tetr4lab/Prices/blob/da82eaf5d8df62468ead9da306a1f32ab077501b/Prices/Prices/Components/Pages/ProductList.razor#L93

https://github.com/tetr4lab/Prices/blob/da82eaf5d8df62468ead9da306a1f32ab077501b/Prices/Prices/Data/Product.cs#L41

https://github.com/tetr4lab/Tetr4labNugetPackages/blob/c767dbab3c5093d46f07f663b34d26a3a2be4553/Tetr4lab/Scripts/ByteArrayHelper.cs#L32-L33

画像種別検出

画像データの中身しか保持していないので、以下の簡易的な手法で種別を検出しています。

https://github.com/tetr4lab/Tetr4labNugetPackages/blob/c767dbab3c5093d46f07f663b34d26a3a2be4553/Tetr4lab/Scripts/ByteArrayHelper.cs#L8-L28

おわりに

お読みいただきありがとうございました。
執筆者は、Blazor、ASP.NETなど諸々において初学者ですので、誤りもあるかと思います。
お気づきの際は、是非コメントや編集リクエストにてご指摘ください。
あるいは、「それでも解らない」、「自分はこう捉えている」などといった、ご意見、ご感想も歓迎いたします。

Discussion