Share via


ドラッグ アンド ドロップ ジェスチャ認識エンジンを追加する

ドラッグ アンド ドロップ ジェスチャを使用すると、項目とそれに関連付けられているデータ パッケージを、連続するジェスチャを使用して、画面上のある位置から別の位置にドラッグできます。 ドラッグ アンド ドロップは 1 つのアプリケーション内で行うことも、あるアプリケーションで開始して別で終了することもできます。

重要

ドラッグ アンド ドロップ ジェスチャの認識は、iOS、Android、およびユニバーサル Windows プラットフォーム (UWP) でサポートされています。 ただし、iOS では、iOS 11 以降のプラットフォームが必要です。

ドラッグ ジェスチャが開始される要素である "ドラッグ ソース" では、データ パッケージ オブジェクトを設定することにより、転送されるデータを提供できます。 ドラッグ ソースが解放されると、ドロップが発生します。 その後、ドラッグ ソースの下にある要素である "ドロップ ターゲット" により、データ パッケージが処理されます。

アプリケーションでドラッグ アンド ドロップを有効にするプロセスは次のとおりです。

  1. DragGestureRecognizer オブジェクトを GestureRecognizers コレクションに追加することによって、要素のドラッグを有効にします。 詳細については、「ドラッグを有効にする」を参照してください。
  2. (省略可能) データ パッケージを構築します。 画像コントロールとテキスト コントロールの場合は Xamarin.Forms によってデータ パッケージが自動的に設定されますが、他のコンテンツについては、ユーザー独自のデータ パッケージを作成する必要があります。 詳細については、「データ パッケージを作成する」を参照してください。
  3. DropGestureRecognizer オブジェクトを GestureRecognizers コレクションに追加することによって、要素のドロップを有効にします。 詳細については、「ドロップを有効にする」を参照してください。
  4. (省略可能) DropGestureRecognizer.DragOver イベントを処理することにより、ドロップ ターゲットによって許可される操作の種類を示します。 詳細については、「DragOver イベントを処理する」を参照してください。
  5. (省略可能) データ パッケージを処理し、ドロップされたコンテンツを受け取ります。 画像データとテキスト データは Xamarin.Forms によってデータ パッケージから自動的に取得されますが、他のコンテンツについてはユーザーがデータ パッケージを処理する必要があります。 詳細については、「データ パッケージを処理する」を参照してください。

Note

CollectionView への、またはそこからの項目のドラッグは、現在サポートされていません。

ドラッグを有効にする

Xamarin.Forms では、ドラッグ ジェスチャの認識は 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 オブジェクトでは、次のプロパティが定義されています。

  • Handled:bool 型、イベント ハンドラーによってイベントが処理されたかどうか、または Xamarin.Forms による独自の処理を続行する必要があるかどうかを示します。
  • Cancel: bool 型、イベントを取り消す必要があるかどうかを示します。
  • Data: DataPackage 型、ドラッグ ソースに付随するデータ パッケージを示します。 これは、読み取り専用プロパティです。

次に示す XAML の例は、Image に関連付けられている DragGestureRecognizer です。

<Image Source="monkeyface.png">
    <Image.GestureRecognizers>
        <DragGestureRecognizer />
    </Image.GestureRecognizers>
</Image>

この例では、Image でドラッグ ジェスチャを開始できます。

ヒント

iOS、Android、UWP では、ドラッグ ジェスチャは長押しの後でドラッグすることによって開始されます。

データ パッケージを作成する

Xamarin.Forms を使用すると、次のコントロールでドラッグが開始された時点で、データ パッケージが自動的に作成されます。

次の表では、テキスト コントロールでドラッグが開始されたときに読み取られるプロパティと、試みられる変換を示します。

コントロール プロパティ 変換
CheckBox IsChecked boolstring に変換されます。
DatePicker Date DateTimestring に変換されます。
Editor Text
Entry Text
Label Text
RadioButton IsChecked boolstring に変換されます。
Switch IsToggled boolstring に変換されます。
TimePicker Time TimeSpanstring に変換されます。

テキストと画像以外のコンテンツの場合は、データ パッケージを自分で作成する必要があります。

データ パッケージは 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>

この例では、DragGestureRecognizerPath オブジェクトにアタッチされます。 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>

この例では、DragGestureRecognizerRectangle オブジェクトにアタッチされます。 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 コレクションを変更して、任意の必要なデータを格納することができます。 この例では、Rectangle のサイズを表す、"Square" キーに対する Square オブジェクトを格納するために、Properties ディクショナリが変更されています。

ドロップを有効にする

Xamarin.Forms では、ドロップ ジェスチャの認識は DropGestureRecognizer クラスによって提供されます。 このクラスでは、次のプロパティが定義されています。

  • AllowDrop: bool 型、ジェスチャ認識エンジンがアタッチされている要素をドロップ ターゲットにすることができるかどうかを示します。 このプロパティの既定値は true です。
  • DragOverCommand: ICommand型、ドラッグ ソースがドロップ ターゲット上にドラッグされたときに実行されます。
  • DragOverCommandParameter: object 型、DragOverCommand に渡されるパラメーター。
  • DragLeaveCommand: ICommand 型、ドラッグ ソースがドロップ ターゲット外にドラッグされたときに実行されます。
  • DragLeaveCommandParameter: object 型、DragLeaveCommand に渡されるパラメーター。
  • DropCommand: ICommand型、ドラッグ ソースがドロップ ターゲットにドロップされたときに実行されます。
  • DropCommandParameter: object 型、DropCommand に渡されるパラメーター。

これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。

また、DropGestureRecognizer クラスでは、AllowDrop プロパティが true の場合に発生する DragOverDragLeave、および Drop イベントも定義されます。 DropGestureRecognizer によってドロップ ターゲット上でドラッグ ソースが認識されると、DragOverCommand が実行されて、DragOver イベントが呼び出されます。 次に、ドラッグ ソースがドロップ ターゲット外にドラッグされると、DropGestureRecognizer によって DragLeaveCommand が実行され、DragLeave イベントが呼び出されます。 最後に、DropGestureRecognizer によってドロップ ターゲット上でドロップ ジェスチャが認識されると、DropCommand が実行されて、Drop イベントが呼び出されます。

DragOver および DragLeave イベントに付随する DragEventArgs クラスでは、次のプロパティが定義されています。

  • Data (DataPackage 型): ドラッグ ソースに関連付けられたデータが格納されます。 このプロパティは読み取り専用です。
  • AcceptedOperation (DataPackageOperation 型): ドロップ ターゲットによって許可されている操作を指定します。

DataPackageOperation 列挙型の詳細については、「DragOver イベントを処理する」を参照してください。

Drop イベントに付随する DropEventArgs クラスでは、次のプロパティが定義されています。

  • Data (DataPackageView 型): データ パッケージの読み取り専用バージョンです。
  • Handled:bool 型、イベント ハンドラーによってイベントが処理されたかどうか、または Xamarin.Forms による独自の処理を続行する必要があるかどうかを示します。

次に示す XAML の例は、Image に関連付けられている DropGestureRecognizer です。

<Image BackgroundColor="Silver"
       HeightRequest="300"
       WidthRequest="250">
    <Image.GestureRecognizers>
        <DropGestureRecognizer />
    </Image.GestureRecognizers>
</Image>

この例では、ドラッグ ソースが Image ドロップ ターゲットにドロップされると、ドラッグ ソースが ImageSource である場合は、ドラッグ ソースがドロップ ターゲットにコピーされます。 これは、Xamarin.Forms によって、ドラッグされた画像とテキストが互換性のあるドロップ ターゲットに自動的にコピーされるためです。

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>

この例では、DropGestureRecognizerImage オブジェクトにアタッチされます。 DragOver イベントは、ドラッグ ソースがドロップ ターゲットの上にドラッグされただけで、ドロップされていない場合に発生し、OnDragOver イベント ハンドラーが実行されます。

void OnDragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.None;
}

この例では、DragEventArgs オブジェクトの AcceptedOperation プロパティが DataPackageOperation.None に設定されます。 これにより、ドラッグ ソースがドロップ ターゲットにドロップされても、アクションは何も実行されません。

データ パッケージを処理する

Drop イベントは、ドロップ ターゲットの上でドラッグ ソースが解放されたときに発生します。 この場合、ドラッグ ソースが次のコントロールにドロップされると、Xamarin.Forms によってデータ パッケージからのデータの取得が自動的に試みられます。

次の表では、テキスト コントロールにテキスト ベースのドラッグ ソースがドロップされたときに設定されるプロパティと、試みられる変換を示します。

コントロール プロパティ 変換
CheckBox IsChecked stringbool に変換されます。
DatePicker Date stringDateTime に変換されます。
Editor Text
Entry Text
Label Text
RadioButton IsChecked stringbool に変換されます。
Switch IsToggled stringbool に変換されます。
TimePicker Time stringTimeSpan に変換されます。

テキストと画像以外のコンテンツの場合は、データ パッケージを自分で処理する必要があります。

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 オブジェクトを取得します。 その後、取得された値に基づくアクションを実行できます。