共用方式為


辨識拖放手勢

.NET 多平臺應用程式 UI (.NET MAUI) 拖放手勢辨識器可讓專案及其相關聯的數據套件使用連續手勢,從螢幕上的一個位置拖曳到另一個位置。 拖放可以在單一應用程式中進行,或者它可以在一個應用程式中啟動,並結束於另一個應用程式。

拖曳來源,這是拖曳手勢起始的專案,可以填入數據封裝物件來提供要傳輸的數據。 放開拖曳來源時,就會發生卸除。 置放目標,也就是拖曳來源下的專案,然後處理數據封裝。

在應用程式中啟用拖放功能的程式如下:

  1. 將物件加入 DragGestureRecognizer 至其 GestureRecognizers 集合,以啟用拖曳專案。 如需詳細資訊,請參閱 啟用拖曳
  2. [選擇性]建置數據封裝。 .NET MAUI 會自動填入影像和文字控件的數據套件,但對於其他內容,您必須建構自己的數據套件。 如需詳細資訊,請參閱 建置數據封裝
  3. 將物件加入 DropGestureRecognizer 至其 GestureRecognizers 集合,以啟用專案卸除。 如需詳細資訊,請參閱 啟用卸除
  4. [選擇性] DropGestureRecognizer.DragOver 處理 事件,以指出置放目標所允許的作業類型。 如需詳細資訊,請參閱 處理 DragOver 事件
  5. [選擇性]處理數據封裝以接收已卸除的內容。 .NET MAUI 會自動從數據套件擷取影像和文字數據,但對於其他內容,您必須處理數據套件。 如需詳細資訊,請參閱 處理數據封裝

啟用拖曳

在 .NET MAUI 中,拖曳手勢辨識是由 DragGestureRecognizer 類別提供。 這個類別會定義下列屬性:

這些屬性是由 BindableProperty 物件所支援,這表示這些屬性可以是數據系結的目標,並設定樣式。

如果 屬性為 ,類別DragGestureRecognizer也會定義 DragStarting 引發的 CanDragDropCompleted 事件。true DragGestureRecognizer當物件偵測到拖曳手勢時,它會執行 DragStartingCommand 並叫用 DragStarting 事件。 然後,當對象偵測到卸除手勢完成時 DragGestureRecognizer ,它會執行 DropCompletedCommand 並叫用 DropCompleted 事件。

事件 DragStartingEventArgs 隨附 DragStarting 的物件會定義下列屬性:

  • Cancelbool別為 的 ,表示是否應該取消事件。
  • DataDataPackage別為 的 ,表示拖曳來源隨附的數據套件。 這是一個唯讀屬性。
  • PlatformArgsPlatformDragStartingEventArgs?別為 的 ,表示與事件相關聯的平臺特定自變數。

在 Android 上,類別 PlatformDragStartingEventArgs 會定義下列屬性:

  • SenderView別為 的 ,表示附加至事件的原生檢視。
  • MotionEventMotionEvent別為 的 ,表示包含拖放狀態資訊的事件。

此外,在Android上,類別 PlatformDragStartingEventArgs 會定義下列方法:

  • SetDragShadowBuilder,它會設定 View.DragShadowBuilder 在拖曳開始時要使用的 。
  • SetClipData,它會設定 ClipData 拖曳開始時要使用的 。
  • SetLocalData,它會設定拖曳開始時要使用的本機數據。
  • SetDragFlags,它會設定 DragFlags 在拖曳開始時要使用的 。

例如,使用 SetClipData 方法來與拖曳的項目產生關聯 ClipData

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
}

事件 DropCompletedEventArgs 隨附 DropCompleted 的 物件會 PlatformArgs 定義 類型 PlatformDropCompletedEventArgs?為的屬性,代表與事件相關聯的平臺特定自變數。

在 Android 上,類別 PlatformDropCompletedEventArgs 會定義下列屬性:

  • SenderView別為 的 ,表示附加至事件的原生檢視。
  • DragEventDragEvent別為 的 ,表示拖放作業期間在各種時間傳送的事件。

下列 XAML 範例顯示 DragGestureRecognizer 附加至 Image的 :

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

在此範例中,可以在上 Image起始拖曳手勢。

提示

拖曳手勢會以長按來起始,後面接著拖曳。

建置數據套件

針對下列控件,.NET MAUI 會自動為您建置數據套件,在起始拖曳時為您:

下表顯示讀取的屬性,以及在文字控件上起始拖曳時嘗試的任何轉換:

控制 屬性 轉換
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 類別表示,其定義下列屬性:

類別 DataPackagePropertySet 代表儲存為 Dictionary<string,object>的屬性包。 如需 類別 DataPackageView 的相關信息,請參閱 處理數據封裝

儲存影像或文字數據

影像或文字數據可以藉由將數據儲存在 或 DataPackage.Text 屬性中DataPackage.Image,來與拖曳來源產生關聯。 您可以在 事件的處理程式 DragStarting 中加入資料。

下列 XAML 範例顯示 DragGestureRecognizer 註冊 事件的處理程式 DragStarting

<Path Stroke="Black"
      StrokeThickness="4">
    <Path.GestureRecognizers>
        <DragGestureRecognizer DragStarting="OnDragStarting" />
    </Path.GestureRecognizers>
    <Path.Data>
        <!-- PathGeometry goes here -->
    </Path.Data>
</Path>

在此範例中,會 DragGestureRecognizer 附加至 Path 物件。 在 DragStartingPath偵測到拖曳手勢時,就會引發 事件,它會執行 OnDragStarting 事件處理程式:

void OnDragStarting(object sender, DragStartingEventArgs e)
{
    e.Data.Text = "My text data goes here";
}

事件 DragStartingEventArgs 隨附 DragStarting 的物件具有 Data 類型的 DataPackage屬性。 在這裡範例中, Text 物件的屬性 DataPackage 會設定為 stringDataPackage接著可以在卸除時存取 ,以擷string取 。

將資料儲存在屬性包中

任何數據,包括影像和文字,都可以藉由將數據儲存在集合中 DataPackage.Properties ,與拖曳來源產生關聯。 您可以在 事件的處理程式 DragStarting 中加入資料。

下列 XAML 範例顯示 DragGestureRecognizer 註冊 事件的處理程式 DragStarting

<Rectangle Stroke="Red"
           Fill="DarkBlue"
           StrokeThickness="4"
           HeightRequest="200"
           WidthRequest="200">
    <Rectangle.GestureRecognizers>
        <DragGestureRecognizer DragStarting="OnDragStarting" />
    </Rectangle.GestureRecognizers>
</Rectangle>

在此範例中,會 DragGestureRecognizer 附加至 Rectangle 物件。 在 DragStartingRectangle偵測到拖曳手勢時,就會引發 事件,它會執行 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));
}

事件 DragStartingEventArgs 隨附 DragStarting 的物件具有 Data 類型的 DataPackage屬性。 物件的 Properties 集合 DataPackage ,這是集合 Dictionary<string, object> ,可以修改以儲存任何必要的數據。 在此範例中 Properties ,字典會修改為儲存 Square 物件,此物件代表對 “Square” 索引鍵的大小 Rectangle

啟用卸除

在 .NET MAUI 中,卸除手勢辨識是由 DropGestureRecognizer 類別提供。 這個類別會定義下列屬性:

這些屬性是由 BindableProperty 物件所支援,這表示這些屬性可以是數據系結的目標,並設定樣式。

類別DropGestureRecognizer也會定義 DragOver屬性為 true時引發的 AllowDropDragLeaveDrop 事件。 DropGestureRecognizer當 辨識拖曳來源到置放目標上方時,它會執行 DragOverCommand 並叫用 DragOver 事件。 然後,如果拖曳來源從置放目標拖曳,則會 DropGestureRecognizer 執行 DragLeaveCommand 並叫用 DragLeave 事件。 最後,當 辨識置放目標上的置放手勢時 DropGestureRecognizer ,它會執行 DropCommand 並叫用 Drop 事件。

DragEventArgs與事件隨附類別 DragOverDragLeave 會定義下列屬性:

在 Android 上,類別 PlatformDragEventArgs 會定義下列屬性:

  • SenderView別為 的 ,表示附加至事件的原生檢視。
  • DragEventDragEvent別為 的 ,表示拖放作業期間在各種時間傳送的事件。

如需列舉的相關信息 DataPackageOperation ,請參閱 處理 DragOver 事件

事件 DropEventArgs 隨附的 Drop 類別會定義下列屬性:

  • DataDataPackageView別為 ,這是數據封裝的唯讀版本。
  • Handledbool別為 的 ,表示事件處理程式是否已處理事件,還是 .NET MAUI 應該繼續自己的處理。
  • PlatformArgsPlatformDropEventArgs?別為 的 ,表示與事件相關聯的平臺特定自變數。

在 Android 上,類別 PlatformDropEventArgs 會定義下列屬性:

  • SenderView別為 的 ,表示附加至事件的原生檢視。
  • DragEventDragEvent別為 的 ,表示拖放作業期間在各種時間傳送的事件。

下列 XAML 範例顯示 DropGestureRecognizer 附加至 Image的 :

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

在此範例中,當拖曳來源卸除至置放目標時 Image ,如果拖曳來源是 ImageSource,則會將拖曳來源複製到置放目標。 .NET MAUI 會自動將拖曳的影像和文字複製到相容的置放目標。

處理 DragOver 事件

DropGestureRecognizer.DragOver您可以選擇性地處理事件,以指出卸除目標允許的作業類型。 您可以在事件隨附DragOver的物件上DragEventArgs,設定 AcceptedOperation 類型 DataPackageOperation為的屬性,以指出允許的作業。

DataPackageOperation 列舉會定義下列成員:

  • None,表示不會執行任何動作。
  • Copy,表示將拖曳來源內容複製到置放目標。

重要

DragEventArgs建立物件時,AcceptedOperation屬性預設為 DataPackageOperation.Copy

下列 XAML 範例顯示 DropGestureRecognizer 註冊 事件的處理程式 DragOver

<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;
}

在這裡範例中, AcceptedOperation 物件的屬性 DragEventArgs 會設定為 DataPackageOperation.None。 此值可確保當拖曳來源卸除至置放目標時,不會採取任何動作。

處理數據套件

Drop 拖曳來源在置放目標上放開時,就會引發 事件。 .NET MAUI 會在拖曳來源卸除至下列控件時,自動嘗試從數據封裝擷取數據:

下表顯示已設定的屬性,以及文字控件上卸除以文字為基礎的拖曳來源時嘗試的任何轉換:

控制 屬性 轉換
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成 。

針對文字和影像以外的內容,您必須自行處理數據封裝。

事件 DropEventArgs 隨附的 Drop 類別會 Data 定義 型別 DataPackageView的屬性。 這個屬性代表數據封裝的唯讀版本。

擷取影像或文字數據

您可以使用 類別中DataPackageView定義的方法,從 事件處理程式Drop中的數據封裝擷取影像或文字數據。

類別 DataPackageView 包含 GetImageAsyncGetTextAsync 方法。 方法 GetImageAsync 會從儲存在 DataPackage.Image 屬性中的數據封裝擷取映像,並傳 Task<ImageSource>回 。 同樣地, GetTextAsync 方法會從儲存在 DataPackage.Text 屬性中的數據封裝擷取文字,並傳 Task<string>回 。

下列範例顯示 Drop 從 資料封裝擷取文字的 Path事件處理程式:

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中的數據封裝擷取任何數據。

類別 DataPackageViewProperties 定義 型別 DataPackagePropertySetView的屬性。 類別 DataPackagePropertySetView 代表儲存為 Dictionary<string, object>的唯讀屬性包。

下列範例顯示 Drop 事件處理程式,從 的數據封裝 Rectangle屬性包擷取數據:

void OnDrop(object sender, DropEventArgs e)
{
    Square square = (Square)e.Data.Properties["Square"];

    // Perform logic to take action based on retrieved value.
}

在此範例中, Square 物件會藉由指定 「Square」 字典索引鍵,從數據封裝的屬性包擷取。 接著可以採取以擷取值為基礎的動作。

取得手勢位置

在 、 DragStartingEventArgsDropEventArgs 物件上DragEventArgs呼叫 GetPosition 方法,即可取得拖放手勢的位置。 方法 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? 物件,該物件會定義相對於螢幕的拖放手勢位置。