ドラッグ アンド ドロップ ジェスチャを認識する
.NET Multi-platform App UI (.NET MAUI) ドラッグ アンド ドロップ ジェスチャ認識エンジンを使用すると、項目とそれに関連付けられているデータ パッケージを、連続するジェスチャを使用して、画面上のある位置から別の位置にドラッグできます。 ドラッグ アンド ドロップは 1 つのアプリケーション内で行うことも、あるアプリケーションで開始して別で終了することもできます。
ドラッグ ジェスチャが開始される要素である "ドラッグ ソース" では、データ パッケージ オブジェクトを設定することにより、転送されるデータを提供できます。 ドラッグ ソースが解放されると、ドロップが発生します。 その後、ドラッグ ソースの下にある要素である "ドロップ ターゲット" により、データ パッケージが処理されます。
アプリでドラッグ アンド ドロップを有効にする手順は次のとおりです。
- DragGestureRecognizer オブジェクトを GestureRecognizers コレクションに追加することによって、要素のドラッグを有効にします。 詳細については、「ドラッグを有効にする」を参照してください。
- (省略可能) データ パッケージを構築します。 画像コントロールやテキスト コントロールの場合は、.NET MAUI によってデータ パッケージを自動的に入力しますが、他のコンテンツについては、ユーザー独自のデータ パッケージを作成する必要があります。 詳細については、「データ パッケージを作成する」を参照してください。
- DropGestureRecognizer オブジェクトを GestureRecognizers コレクションに追加することによって、要素のドロップを有効にします。 詳細については、「ドロップを有効にする」を参照してください。
- (省略可能)
DropGestureRecognizer.DragOver
イベントを処理することにより、ドロップ ターゲットによって許可される操作の種類を示します。 詳細については、「DragOver イベントを処理する」を参照してください。 - (省略可能) データ パッケージを処理し、ドロップされたコンテンツを受け取ります。 画像データとテキスト データは .NET MAUI によってデータ パッケージから自動的に取得されますが、他のコンテンツについてはユーザーがデータ パッケージを処理する必要があります。 詳細については、「データ パッケージを処理する」を参照してください。
ドラッグを有効にする
.NET MAUI では、ドラッグ ジェスチャの認識機能は DragGestureRecognizer クラスで提供されます。 このクラスでは、次のプロパティが定義されています。
- CanDrag:
bool
型、ジェスチャ認識エンジンがアタッチされている要素をドラッグ ソースにすることができるかどうかを示します。 このプロパティの既定値はtrue
です。 - DragStartingCommand: ICommand型、ドラッグ ジェスチャが最初に認識されたときに実行されます。
- DragStartingCommandParameter:
object
型、DragStartingCommand に渡されるパラメーター。 - DropCompletedCommand: ICommand型、ドラッグ ソースがドロップされたときに実行されます。
- DropCompletedCommandParameter:
object
型、DropCompletedCommand に渡されるパラメーター。
これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。
DragGestureRecognizer クラスは、CanDrag プロパティが true
の場合に発生する DragStarting イベントと DropCompleted イベントも定義します。 DragGestureRecognizer オブジェクトによってドラッグ ジェスチャが検出されると、DragStartingCommand が実行されて、DragStarting イベントが呼び出されます。 その後、DragGestureRecognizer オブジェクトによってドロップ ジェスチャの完了が検出されると、DropCompletedCommand が実行されて、DropCompleted イベントが呼び出されます。
DragStarting イベントに付随する DragStartingEventArgs オブジェクトでは、次のプロパティが定義されています。
- Cancel:
bool
型、イベントを取り消す必要があるかどうかを示します。 - Data: DataPackage 型、ドラッグ ソースに付随するデータ パッケージを示します。 これは、読み取り専用プロパティです。
- PlatformArgs:
PlatformDragStartingEventArgs?
型、イベントに関連付けられているプラットフォーム固有の引数を表します。
Android では、PlatformDragStartingEventArgs クラスは次のプロパティを定義します。
Sender
(View 型): イベントにアタッチされたネイティブ ビューを表します。MotionEvent
: MotionEvent 型、ドラッグ アンド ドロップ状態の情報を含むイベントを表します。
さらに、Android では、PlatformDragStartingEventArgs クラスは次のメソッドを定義します。
SetDragShadowBuilder
: ドラッグの開始時に使用する View.DragShadowBuilder を設定します。SetClipData
: ドラッグの開始時に使用する ClipData を設定します。SetLocalData
: ドラッグの開始時に使用するローカル データを設定します。SetDragFlags
: ドラッグの開始時に使用する DragFlags を設定します。
たとえば、ドラッグした項目に ClipData を関連付けるには、SetClipData
メソッドを使用します。
void OnDragStarting(object sender, DragStartingEventArgs e)
{
#if ANDROID
string content = "insert your content here";
e.PlatformArgs.SetClipData(Android.Content.ClipData.NewPlainText("Drag data", content));
#endif
}
DropCompleted イベントに付随する DropCompletedEventArgs オブジェクトには、このイベントに関連付けられているプラットフォーム固有の引数を表す、PlatformDropCompletedEventArgs?
型の PlatformArgs プロパティを定義します。
Android では、PlatformDropCompletedEventArgs クラスは次のプロパティを定義します。
次に示す XAML の例は、Image に関連付けられている DragGestureRecognizer です。
<Image Source="monkeyface.png">
<Image.GestureRecognizers>
<DragGestureRecognizer />
</Image.GestureRecognizers>
</Image>
この例では、Image でドラッグ ジェスチャを開始できます。
ヒント
ドラッグ ジェスチャは、長押しした後にドラッグすると開始されます。
データ パッケージを作成する
次のコントロールの場合、ドラッグを開始すると、.NET MAUI によりデータ パッケージが自動的に作成されます。
- テキスト コントロール。 CheckBox、DatePicker、Editor、Entry、Label、RadioButton、Switch、TimePicker の各オブジェクトから、テキスト値をドラッグできます。
- 画像コントロール。 Button、Image、ImageButton の各コントロールから、画像をドラッグできます。
次の表では、テキスト コントロールでドラッグが開始されたときに読み取られるプロパティと、試みられる変換を示します。
コントロール | プロパティ | 変換 |
---|---|---|
CheckBox | IsChecked |
bool は string に変換されます。 |
DatePicker | Date |
DateTime は string に変換されます。 |
Editor | Text |
|
Entry | Text |
|
Label | Text |
|
RadioButton | IsChecked |
bool は string に変換されます。 |
Switch | IsToggled |
bool は string に変換されます。 |
TimePicker | Time |
TimeSpan は string に変換されます。 |
テキストと画像以外のコンテンツの場合は、データ パッケージを自分で作成する必要があります。
データ パッケージは DataPackage クラスによって表され、次のプロパティが定義されています。
- Properties: DataPackagePropertySet型、DataPackage に含まれるデータを構成するプロパティのコレクションです。 このプロパティは、読み取り専用のプロパティです。
- Image: ImageSource 型、DataPackage に含まれる画像です。
- Text:
string
型、DataPackage に含まれるテキストです。 - View: DataPackageView 型、DataPackage の読み取り専用バージョンです。
DataPackagePropertySet クラスは、Dictionary<string,object>
として格納されるプロパティ バッグを表します。 DataPackageView クラスの詳細については、「データ パッケージを処理する」を参照してください。
画像データまたはテキスト データを格納する
画像データまたはテキスト データをドラッグ ソースと関連付けるには、DataPackage.Image
または DataPackage.Text
プロパティにデータを格納します。 DragStarting イベントのハンドラーにデータを追加できます。
次の XAML の例では、DragStarting イベントのハンドラーを登録する DragGestureRecognizer を示します。
<Path Stroke="Black"
StrokeThickness="4">
<Path.GestureRecognizers>
<DragGestureRecognizer DragStarting="OnDragStarting" />
</Path.GestureRecognizers>
<Path.Data>
<!-- PathGeometry goes here -->
</Path.Data>
</Path>
この例では、DragGestureRecognizer が Path オブジェクトにアタッチされます。 Path でドラッグ ジェスチャが検出されると DragStarting イベントが発生し、OnDragStarting
イベント ハンドラーが実行されます。
void OnDragStarting(object sender, DragStartingEventArgs e)
{
e.Data.Text = "My text data goes here";
}
DragStarting イベントに付随する DragStartingEventArgs オブジェクトには、DataPackage 型の Data
プロパティがあります。 この例では、DataPackage オブジェクトの Text
プロパティが string
に設定されます。 その後、ドロップ時に DataPackage にアクセスして、string
を取得できます。
プロパティ バッグにデータを格納する
画像やテキストを含むどのようなデータでも、DataPackage.Properties
コレクションにデータを格納することにより、ドラッグ ソースと関連付けることができます。 DragStarting イベントのハンドラーにデータを追加できます。
次の XAML の例では、DragStarting イベントのハンドラーを登録する DragGestureRecognizer を示します。
<Rectangle Stroke="Red"
Fill="DarkBlue"
StrokeThickness="4"
HeightRequest="200"
WidthRequest="200">
<Rectangle.GestureRecognizers>
<DragGestureRecognizer DragStarting="OnDragStarting" />
</Rectangle.GestureRecognizers>
</Rectangle>
この例では、DragGestureRecognizer が Rectangle オブジェクトにアタッチされます。 Rectangle でドラッグ ジェスチャが検出されると DragStarting イベントが発生し、OnDragStarting
イベント ハンドラーが実行されます。
void OnDragStarting(object sender, DragStartingEventArgs e)
{
Shape shape = (sender as Element).Parent as Shape;
e.Data.Properties.Add("Square", new Square(shape.Width, shape.Height));
}
DragStarting イベントに付随する DragStartingEventArgs オブジェクトには、DataPackage 型の Data
プロパティがあります。 Dictionary<string, object>
コレクションである DataPackage オブジェクトの Properties
コレクションを変更して、任意の必要なデータを格納することができます。 この例では、"Square" キーに対する Rectangle のサイズを表す Square
オブジェクトを格納するために、Properties
ディクショナリが変更されています。
ドロップを有効にする
.NET MAUI では、ドロップ ジェスチャの認識は DropGestureRecognizer クラスによって提供されます。 このクラスでは、次のプロパティが定義されています。
- AllowDrop:
bool
型、ジェスチャ認識エンジンがアタッチされている要素をドロップ ターゲットにすることができるかどうかを示します。 このプロパティの既定値はtrue
です。 - DragOverCommand: ICommand型、ドラッグ ソースがドロップ ターゲット上にドラッグされたときに実行されます。
- DragOverCommandParameter:
object
型、DragOverCommand
に渡されるパラメーター。 - DragLeaveCommand: ICommand 型、ドラッグ ソースがドロップ ターゲット外にドラッグされたときに実行されます。
- DragLeaveCommandParameter:
object
型、DragLeaveCommand
に渡されるパラメーター。 - DropCommand: ICommand型、ドラッグ ソースがドロップ ターゲットにドロップされたときに実行されます。
- DropCommandParameter:
object
型、DropCommand
に渡されるパラメーター。
これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。
また、DropGestureRecognizer クラスには、AllowDrop プロパティが true
の場合に発生する DragOver、DragLeave、Drop の各イベントも定義されます。 DropGestureRecognizer によってドロップ ターゲット上でドラッグ ソースが認識されると、DragOverCommand が実行されて、DragOver イベントが呼び出されます。 次に、ドラッグ ソースがドロップ ターゲット外にドラッグされると、DropGestureRecognizer によって DragLeaveCommand が実行され、DragLeave イベントが呼び出されます。 最後に、DropGestureRecognizer によってドロップ ターゲット上でドロップ ジェスチャが認識されると、DropCommand が実行されて、Drop イベントが呼び出されます。
DragOver と DragLeave のイベントに付随する DragEventArgs クラスでは、次のプロパティが定義されています。
- Data (DataPackage 型): ドラッグ ソースに関連付けられたデータが格納されます。 このプロパティは読み取り専用です。
- AcceptedOperation (DataPackageOperation 型): ドロップ ターゲットによって許可されている操作を指定します。
- PlatformArgs (
PlatformDragEventArgs?
型): イベントに関連付けられているプラットフォーム固有の引数を表します。
Android では、PlatformDragEventArgs クラスは次のプロパティを定義します。
DataPackageOperation 列挙型の詳細については、「DragOver イベントを処理する」を参照してください。
Drop イベントに付随する DropEventArgs クラスでは、次のプロパティが定義されています。
- Data (DataPackageView 型): データ パッケージの読み取り専用バージョンです。
- Handled (
bool
型): イベント ハンドラーでイベントが処理されたか、または .NET MAUI で独自の処理を続行する必要があるかを示します。 - PlatformArgs (
PlatformDropEventArgs?
型): イベントに関連付けられているプラットフォーム固有の引数を表します。
Android では、PlatformDropEventArgs クラスは次のプロパティを定義します。
次に示す XAML の例は、Image に関連付けられている DropGestureRecognizer です。
<Image BackgroundColor="Silver"
HeightRequest="300"
WidthRequest="250">
<Image.GestureRecognizers>
<DropGestureRecognizer />
</Image.GestureRecognizers>
</Image>
この例では、ドラッグ ソースが Image ドロップ ターゲットにドロップされると、ドラッグ ソースが ImageSource である場合は、ドラッグ ソースがドロップ ターゲットにコピーされます。 .NET MAUI は、ドラッグされた画像とテキストを互換性のあるドロップ ターゲットに自動的にコピーします。
DragOver イベントを処理する
必要に応じて DropGestureRecognizer.DragOver
イベントを処理し、ドロップ ターゲットによって許可されている操作の種類を示すことができます。 DragOver イベントに付随する DragEventArgs オブジェクトに対して DataPackageOperation 型の AcceptedOperation
プロパティを設定することで、許容される操作を指定できます。
DataPackageOperation 列挙型には、次のメンバーが定義されています。
None
は、何も実行されないことを示します。Copy
は、ドラッグ ソースのコンテンツがドロップ ターゲットにコピーされることを示します。
重要
DragEventArgs オブジェクトが作成されるとき、AcceptedOperation
プロパティの既定値は DataPackageOperation.Copy
に設定されます。
次の XAML の例では、DragOver イベントのハンドラーを登録する DropGestureRecognizer を示します。
<Image BackgroundColor="Silver"
HeightRequest="300"
WidthRequest="250">
<Image.GestureRecognizers>
<DropGestureRecognizer DragOver="OnDragOver" />
</Image.GestureRecognizers>
</Image>
この例では、DropGestureRecognizer が Image オブジェクトにアタッチされます。 DragOver イベントは、ドラッグ ソースがドロップ ターゲットの上にドラッグされ、まだドロップされていない場合に発生し、OnDragOver
イベント ハンドラーが実行されます。
void OnDragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.None;
}
この例では、DragEventArgs オブジェクトの AcceptedOperation
プロパティが DataPackageOperation.None
に設定されます。 この値により、ドラッグ ソースがドロップ ターゲット上にドロップされても、アクションが実行されなくなります。
データ パッケージを処理する
Drop イベントは、ドロップ ターゲットの上でドラッグ ソースがリリースされた場合に発生します。 ドラッグ ソースが次のコントロールにドロップされると、.NET MAUI はデータ パッケージからのデータの取得を自動的に試行します。
- テキスト コントロール。 CheckBox、DatePicker、Editor、Entry、Label、RadioButton、Switch、TimePicker の各オブジェクトに、テキスト値をドロップできます。
- 画像コントロール。 Button、Image、ImageButton の各コントロールに、画像をドロップできます。
次の表では、テキスト コントロールにテキスト ベースのドラッグ ソースがドロップされた場合に設定されるプロパティやどのような変換が試行されるかを示します。
コントロール | プロパティ | 変換 |
---|---|---|
CheckBox | IsChecked |
string は bool に変換されます。 |
DatePicker | Date |
string は DateTime に変換されます。 |
Editor | Text |
|
Entry | Text |
|
Label | Text |
|
RadioButton | IsChecked |
string は bool に変換されます。 |
Switch | IsToggled |
string は bool に変換されます。 |
TimePicker | Time |
string は TimeSpan に変換されます。 |
テキストと画像以外のコンテンツの場合は、データ パッケージを自分で処理する必要があります。
Drop イベントに付随する DropEventArgs クラスでは、DataPackageView 型の Data
プロパティが定義されています。 このプロパティは、データ パッケージの読み取り専用バージョンを表します。
画像データまたはテキスト データを取得する
DataPackageView クラスで定義されているメソッドを使用して、Drop イベントのハンドラー内でデータ パッケージから画像データまたはテキスト データを取得できます。
DataPackageView クラスには、GetImageAsync
メソッドと GetTextAsync
メソッドが含まれています。 GetImageAsync
メソッドは、DataPackage.Image
プロパティに格納されたデータ パッケージから画像を取得し、Task<ImageSource>
を返します。 同様に、GetTextAsync
メソッドは、DataPackage.Text
プロパティに格納されたデータ パッケージからテキストを取得し、Task<string>
を返します。
次の例では、Path に対するデータ パッケージからテキストを取得する Drop
イベント ハンドラーが示されています。
async void OnDrop(object sender, DropEventArgs e)
{
string text = await e.Data.GetTextAsync();
// Perform logic to take action based on the text value.
}
この例では、GetTextAsync
メソッドを使用してデータ パッケージからテキスト データが取得されます。 その後、テキスト値に基づくアクションを実行できます。
プロパティ バッグからデータを取得する
データ パッケージの Properties
コレクションにアクセスすることにより、Drop イベントのハンドラー内でデータ パッケージから任意のデータを取得できます。
DataPackageView クラスでは、DataPackagePropertySetView
型の Properties
プロパティが定義されています。 DataPackagePropertySetView
クラスは、Dictionary<string, object>
として格納される読み取り専用のプロパティ バッグを表します。
次の例では、Rectangle に対するデータ パッケージのプロパティ バッグからデータを取得する Drop イベント ハンドラーが示されています。
void OnDrop(object sender, DropEventArgs e)
{
Square square = (Square)e.Data.Properties["Square"];
// Perform logic to take action based on retrieved value.
}
この例では、"Square" ディクショナリ キーを指定することにより、データ パッケージのプロパティ バッグから Square
オブジェクトを取得します。 その後、取得された値に基づくアクションを実行できます。
アプリケーション間のドラッグ アンド ドロップ
iOS、Mac Catalyst、および Windows では、.NET MAUI アプリケーションで終わる対応するドロップ操作を使用して、1 つのアプリケーションでドラッグを開始できます。 項目のドラッグ元となるアプリは source アプリケーションであり、項目がドロップされる .NET MAUI アプリは destination アプリケーションです。
source アプリケーションから Android 上の .NET MAUI destination アプリケーションにドラッグすることはできません。
ジェスチャの位置を取得する
ドラッグ アンド ドロップ ジェスチャが発生した位置は、GetPosition メソッドを、DragEventArgs、DragStartingEventArgs、DropEventArgs オブジェクトで呼び出すことによって取得できます。 GetPosition メソッドは Element?
引数を受け取り、Point?
オブジェクトとして位置を返します。
void OnDragStarting(object sender, DragStartingEventArgs e)
{
// Position relative to screen
Point? screenPosition = e.GetPosition(null);
// Position relative to specified element
Point? relativeToImagePosition = e.GetPosition(image);
}
Element?
引数は、位置を取得する必要がある要素を定義します。 この引数として null
値を指定すると、GetPosition メソッドは画面に対するドラッグ または ドロップ ジェスチャの位置を定義する Point?
オブジェクトを返します。
.NET MAUI