2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Avaloniaでドラッグ&ドロップでファイルを受け取る【Drag and Drop】

Posted at

Avaloniaという、C#でマルチプラットフォームなGUIが作れるフレームワークを試していました
AvaloniaはWPFの精神的後継者を自称するなど全体的にWPFっぽく(WPF触ったことないけど)、簡単なことであれば「WPF + やりたいこと」で検索してそのとおりにやればできることが多いです

が、ドラッグアンドドロップはそうでもなかった上情報がかなり少なさそうなので書きます

完成品

起動すると文字入りのウィンドウが開き、ウィンドウにファイルやフォルダを投げると絶対パスを、テキストを選択して投げるとテキストを文字で表示します
MVVMテンプレートから作成しました
image.png
画像はFドライブのProgram Filesフォルダを投げた場合です

GitHubに上げてます

Windows11でしか動作確認していません

参考

Mamma Mia Dev様の解説動画

Redditで同じようなことをしていた質問

DragEventArgsの公式リファレンス
https://reference.avaloniaui.net/api/Avalonia.Input/DragEventArgs/
IDataObjectの公式リファレンス
https://reference.avaloniaui.net/api/Avalonia.Input/IDataObject/

やる

まず、Avaloniaでドラッグアンドドロップを実装する方法は公式ドキュメントには全然情報がなく、上記参考をもとに適当に書いたものなので間違いあったらごめんなさい

MainWindow.axaml
<Window 省略~
	    DragDrop.AllowDrop="True">

ドラッグアンドドロップを受け入れたいコントロールのDragDrop.AllowDropプロパティをTrueにします

MainWindow.axaml.cs
public partial class MainWindow : Window
{
	public MainWindow()
	{
		InitializeComponent();
		AddHandler(DragDrop.DropEvent, DropFile); //登録を忘れない 多分xaml側では不可能
	}

	private void DropFile(object? sender, DragEventArgs e)
	{
		var dropData = e.Data;
		//ここに受け取った情報を使う処理を書く
	}
}

コードビハインドでファイルがドロップされたときの処理を書いていきますが、この処理をコンストラクタにてAddHandler(DragDrop.DropEvent, DropFile);で登録しなければいけないようです

DragEventArgsの使い勝手がWPFのそれと若干違う?

あとはDragEventArgsから受け取ったやつ使って処理書けばOK!なんですが
このDragEventArgs型はWPFのそれとは別物で、受け取れるDataも別物になります
私はここで苦戦しました

このDataはAvalonia.Input.IDataObject型で、例えば受け取ったもののパスが欲しいなとなったときに、前述の公式リファレンスを見るとGetFileNames()といういかにもなメソッドが使えるようなのですが実際には使えません(なんでだ?)

手探りでやった結果このような形に行きつきました
CenterTextという名前のstring型プロパティにパスをセットするコードの一部です

if(data.GetText() != null)
{
    //もし受け取ったのがテキストであればそれにセット
	CenterText = data.GetText();
	return;
}
else
{
	if(data.GetFiles != null)
	{
        //複数ファイルをドロップしても全部のパスを読むようにする
		List<string> path = new();
		foreach (var item in data.GetFiles())
		{
			path.Add(item.Path.ToString());
		}
		if(path.Count > 0)
		{
			CenterText = string.Join("\n", path);
		}
	}
		
}

GetFilesというメソッドを使いファイルのコレクションを取得しています
ちなみにGetFilesメソッドですがこっちは使えるのになぜかリファレンスに乗っていません

まとめ

WPFは枯れた技術だからか情報が多くてすごい
リファレンスうんぬんは私が間違っている可能性もあるので、教えていただければ修正します

参考になれば幸いです

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?