辨識拖放手勢
.NET 多平臺應用程式 UI (.NET MAUI) 拖放手勢辨識器可讓專案及其相關聯的數據套件使用連續手勢,從螢幕上的一個位置拖曳到另一個位置。 拖放可以在單一應用程式中進行,或者它可以在一個應用程式中啟動,並結束於另一個應用程式。
拖曳來源,這是拖曳手勢起始的專案,可以填入數據封裝物件來提供要傳輸的數據。 放開拖曳來源時,就會發生卸除。 置放目標,也就是拖曳來源下的專案,然後處理數據封裝。
在應用程式中啟用拖放功能的程式如下:
- 將物件加入 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也會定義 DragStarting 引發的 CanDrag 和 DropCompleted 事件。true
DragGestureRecognizer當物件偵測到拖曳手勢時,它會執行 DragStartingCommand 並叫用 DragStarting 事件。 然後,當對象偵測到卸除手勢完成時 DragGestureRecognizer ,它會執行 DropCompletedCommand 並叫用 DropCompleted 事件。
事件 DragStartingEventArgs 隨附 DragStarting 的物件會定義下列屬性:
- Cancel型
bool
別為 的 ,表示是否應該取消事件。 - Data型 DataPackage別為 的 ,表示拖曳來源隨附的數據套件。 這是一個唯讀屬性。
- PlatformArgs型
PlatformDragStartingEventArgs?
別為 的 ,表示與事件相關聯的平臺特定自變數。
在 Android 上,類別 PlatformDragStartingEventArgs 會定義下列屬性:
Sender
型 View別為 的 ,表示附加至事件的原生檢視。MotionEvent
型 MotionEvent別為 的 ,表示包含拖放狀態資訊的事件。
此外,在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 會定義下列屬性:
下列 XAML 範例顯示 DragGestureRecognizer 附加至 Image的 :
<Image Source="monkeyface.png">
<Image.GestureRecognizers>
<DragGestureRecognizer />
</Image.GestureRecognizers>
</Image>
在此範例中,可以在上 Image起始拖曳手勢。
提示
拖曳手勢會以長按來起始,後面接著拖曳。
建置數據套件
針對下列控件,.NET MAUI 會自動為您建置數據套件,在起始拖曳時為您:
- 文字控制件。 文字值可以從 、、、、、、、 和物件拖曳CheckBox。 LabelEntryDatePickerTimePickerSwitchRadioButtonEditor
- 影像控制件。 您可以從、 Image和 ImageButton 控制件拖曳Button影像。
下表顯示讀取的屬性,以及在文字控件上起始拖曳時嘗試的任何轉換:
控制 | 屬性 | 轉換 |
---|---|---|
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.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 物件。 在 DragStarting 上 Path偵測到拖曳手勢時,就會引發 事件,它會執行 OnDragStarting
事件處理程式:
void OnDragStarting(object sender, DragStartingEventArgs e)
{
e.Data.Text = "My text data goes here";
}
事件 DragStartingEventArgs 隨附 DragStarting 的物件具有 Data
類型的 DataPackage屬性。 在這裡範例中, Text
物件的屬性 DataPackage 會設定為 string
。 DataPackage接著可以在卸除時存取 ,以擷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 物件。 在 DragStarting 上 Rectangle偵測到拖曳手勢時,就會引發 事件,它會執行 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 類別提供。 這個類別會定義下列屬性:
- AllowDrop型
bool
別為 的 ,指出筆勢辨識器所附加的專案是否可以是置放目標。 此屬性的預設值為true
。 - DragOverCommand型 ICommand別為 的 ,會在拖曳來源拖曳到置放目標上方時執行。
- DragOverCommandParameter,屬於
object
類型,這是傳遞至DragOverCommand
的參數。 - DragLeaveCommand類型 ICommand為 ,會在拖曳來源從置放目標拖曳時執行。
- DragLeaveCommandParameter,屬於
object
類型,這是傳遞至DragLeaveCommand
的參數。 - DropCommand型 ICommand別為 的 ,會在拖曳來源卸除至置放目標時執行。
- DropCommandParameter,屬於
object
類型,這是傳遞至DropCommand
的參數。
這些屬性是由 BindableProperty 物件所支援,這表示這些屬性可以是數據系結的目標,並設定樣式。
類別DropGestureRecognizer也會定義 DragOver屬性為 true
時引發的 AllowDrop 、 DragLeave和 Drop 事件。 DropGestureRecognizer當 辨識拖曳來源到置放目標上方時,它會執行 DragOverCommand 並叫用 DragOver 事件。 然後,如果拖曳來源從置放目標拖曳,則會 DropGestureRecognizer 執行 DragLeaveCommand 並叫用 DragLeave 事件。 最後,當 辨識置放目標上的置放手勢時 DropGestureRecognizer ,它會執行 DropCommand 並叫用 Drop 事件。
DragEventArgs與事件隨附類別 DragOverDragLeave 會定義下列屬性:
- Data型 DataPackage別為 的 ,其中包含與拖曳來源相關聯的數據。 這個屬性是唯讀的。
- AcceptedOperation型 DataPackageOperation別為 的 ,指定卸除目標允許的作業。
- PlatformArgs型
PlatformDragEventArgs?
別為 的 ,表示與事件相關聯的平臺特定自變數。
在 Android 上,類別 PlatformDragEventArgs 會定義下列屬性:
如需列舉的相關信息 DataPackageOperation ,請參閱 處理 DragOver 事件。
事件 DropEventArgs 隨附的 Drop 類別會定義下列屬性:
- Data型 DataPackageView別為 ,這是數據封裝的唯讀版本。
- Handled型
bool
別為 的 ,表示事件處理程式是否已處理事件,還是 .NET MAUI 應該繼續自己的處理。 - PlatformArgs型
PlatformDropEventArgs?
別為 的 ,表示與事件相關聯的平臺特定自變數。
在 Android 上,類別 PlatformDropEventArgs 會定義下列屬性:
下列 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、、DatePickerEditor、、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 成 。 |
針對文字和影像以外的內容,您必須自行處理數據封裝。
事件 DropEventArgs 隨附的 Drop 類別會 Data
定義 型別 DataPackageView的屬性。 這個屬性代表數據封裝的唯讀版本。
擷取影像或文字數據
您可以使用 類別中DataPackageView定義的方法,從 事件處理程式Drop中的數據封裝擷取影像或文字數據。
類別 DataPackageView 包含 GetImageAsync
和 GetTextAsync
方法。 方法 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中的數據封裝擷取任何數據。
類別 DataPackageView 會 Properties
定義 型別 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」 字典索引鍵,從數據封裝的屬性包擷取。 接著可以採取以擷取值為基礎的動作。
取得手勢位置
在 、 DragStartingEventArgs或 DropEventArgs 物件上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?
物件,該物件會定義相對於螢幕的拖放手勢位置。