新增拖放手勢辨識器
拖放手勢可讓專案及其相關聯的數據套件使用連續手勢,從螢幕上的一個位置拖曳到另一個位置。 拖放可以在單一應用程式中進行,或者它可以在一個應用程式中啟動,並結束於另一個應用程式。
重要
iOS、Android 和 通用 Windows 平台 (UWP) 支援拖放手勢的辨識。 不過,在 iOS 上,需要 iOS 11 的最低平臺。
拖曳來源,這是拖曳手勢起始的專案,可以填入數據封裝物件來提供要傳輸的數據。 放開拖曳來源時,就會發生卸除。 置放目標,也就是拖曳來源下的專案,然後處理數據封裝。
在應用程式中啟用拖放的程式如下:
- 將物件加入
DragGestureRecognizer
至其GestureRecognizers
集合,以啟用拖曳專案。 如需詳細資訊,請參閱 啟用拖曳。 - [選擇性]建置數據封裝。 Xamarin.Forms 會自動填入影像和文字控件的數據套件,但對於其他內容,您必須建構自己的數據套件。 如需詳細資訊,請參閱 建置數據封裝。
- 藉由加入
DropGestureRecognizer
物件的GestureRecognizers
集合來啟用專案卸除。 如需詳細資訊,請參閱 啟用卸除。 - [選擇性]
DropGestureRecognizer.DragOver
處理 事件,以指出置放目標所允許的作業類型。 如需詳細資訊,請參閱 處理 DragOver 事件。 - [選擇性]處理數據封裝以接收已卸除的內容。 Xamarin.Forms 會自動從數據封裝擷取影像和文字數據,但對於其他內容,您必須處理數據封裝。 如需詳細資訊,請參閱 處理數據封裝。
注意
目前不支援從 CollectionView
中拖曳專案。
啟用拖曳
在 中 Xamarin.Forms,拖曳手勢辨識是由 DragGestureRecognizer
類別提供。 這個類別會定義下列屬性:
CanDrag
型bool
別為 的 ,指出筆勢辨識器所附加的專案是否可以是拖曳來源。 此屬性的預設值為true
。DragStartingCommand
,屬於 類型ICommand
,這是第一次辨識拖曳手勢時所執行的。DragStartingCommandParameter
,屬於object
類型,這是傳遞至DragStartingCommand
的參數。DropCompletedCommand
型別為ICommand
的 ,會在卸除拖曳來源時執行。DropCompletedCommandParameter
,屬於object
類型,這是傳遞至DropCompletedCommand
的參數。
這些屬性是由 BindableProperty
物件所支援,這表示這些屬性可以是數據系結的目標,並設定樣式。
類別 DragGestureRecognizer
也會定義 DragStarting
和 DropCompleted
事件,前提是 CanDrag
屬性為 true
。 DragGestureRecognizer
當物件偵測到拖曳手勢時,它會執行 DragStartingCommand
並叫用 DragStarting
事件。 然後,當對象偵測到卸除手勢完成時 DragGestureRecognizer
,它會執行 DropCompletedCommand
並叫用 DropCompleted
事件。
事件 DragStartingEventArgs
隨附 DragStarting
的物件會定義下列屬性:
Handled
型bool
別為 的 ,表示事件處理程式是否已處理事件,還是應該 Xamarin.Forms 繼續自己的處理。Cancel
型bool
別為 的 ,表示是否應該取消事件。Data
型DataPackage
別為 的 ,表示拖曳來源隨附的數據套件。 這是一個唯讀屬性。
下列 XAML 範例顯示 DragGestureRecognizer
附加至 Image
的 :
<Image Source="monkeyface.png">
<Image.GestureRecognizers>
<DragGestureRecognizer />
</Image.GestureRecognizers>
</Image>
在此範例中,可以在上 Image
起始拖曳手勢。
提示
在iOS、Android和UWP上,拖曳手勢會以長按後再拖曳來起始。
建置數據套件
Xamarin.Forms 會在起始拖曳時,自動為您建置數據封裝,以進行下列控件:
- 文字控制件。 文字值可以從 、、、、、、、 和物件拖曳
CheckBox
。Label
Entry
DatePicker
TimePicker
Switch
RadioButton
Editor
- 影像控制件。 您可以從、
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
。
啟用卸除
在 中 Xamarin.Forms,卸除手勢辨識是由 DropGestureRecognizer
類別提供。 這個類別會定義下列屬性:
AllowDrop
型bool
別為 的 ,指出筆勢辨識器所附加的專案是否可以是置放目標。 此屬性的預設值為true
。DragOverCommand
型ICommand
別為 的 ,會在拖曳來源拖曳到置放目標上方時執行。DragOverCommandParameter
,屬於object
類型,這是傳遞至DragOverCommand
的參數。DragLeaveCommand
類型ICommand
為 ,會在拖曳來源從置放目標拖曳時執行。DragLeaveCommandParameter
,屬於object
類型,這是傳遞至DragLeaveCommand
的參數。DropCommand
型ICommand
別為 的 ,會在拖曳來源卸除至置放目標時執行。DropCommandParameter
,屬於object
類型,這是傳遞至DropCommand
的參數。
這些屬性是由 BindableProperty
物件所支援,這表示這些屬性可以是數據系結的目標,並設定樣式。
類別 DropGestureRecognizer
也會定義 DragOver
、 DragLeave
、 和 Drop
事件,前提是 AllowDrop
屬性為 true
。 DropGestureRecognizer
當 辨識拖曳來源到置放目標上方時,它會執行 DragOverCommand
並叫用 DragOver
事件。 然後,如果拖曳來源從置放目標拖曳,則會 DropGestureRecognizer
執行 DragLeaveCommand
並叫用 DragLeave
事件。 最後,當 辨識置放目標上的置放手勢時 DropGestureRecognizer
,它會執行 DropCommand
並叫用 Drop
事件。
DragEventArgs
與 DragLeave
事件隨附類別 DragOver
會定義下列屬性:
Data
型DataPackage
別為 的 ,其中包含與拖曳來源相關聯的數據。 這個屬性是唯讀的。AcceptedOperation
型DataPackageOperation
別為 的 ,指定卸除目標允許的作業。
如需列舉的相關信息 DataPackageOperation
,請參閱 處理 DragOver 事件。
事件 DropEventArgs
隨附的 Drop
類別會定義下列屬性:
Data
型DataPackageView
別為 ,這是數據封裝的唯讀版本。Handled
型bool
別為 的 ,表示事件處理程式是否已處理事件,還是應該 Xamarin.Forms 繼續自己的處理。
下列 XAML 範例顯示 DropGestureRecognizer
附加至 Image
的 :
<Image BackgroundColor="Silver"
HeightRequest="300"
WidthRequest="250">
<Image.GestureRecognizers>
<DropGestureRecognizer />
</Image.GestureRecognizers>
</Image>
在此範例中,當拖曳來源在置放目標上 Image
卸除時,只要拖曳來源是 ImageSource
,拖曳來源就會複製到置放目標。 Xamarin.Forms這是因為自動將拖曳的影像和文字複製到相容的置放目標。
處理 DragOver 事件
DropGestureRecognizer.DragOver
您可以選擇性地處理事件,以指出卸除目標允許的作業類型。 若要達成此目的,可以藉由設定 AcceptedOperation
事件隨附DragOver
之 物件的 屬性,類型DataPackageOperation
DragEventArgs
為 。
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
拖曳來源放開至置放目標時,就會引發事件。 當發生這種情況時,當拖曳來源卸除至下列控件時, Xamarin.Forms 會自動嘗試從數據封裝擷取數據:
- 文字控制件。 文字值可以卸除至
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 成 。 |
針對文字和影像以外的內容,您必須自行處理數據封裝。
事件 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」 字典索引鍵,從數據封裝的屬性包擷取。 接著可以採取以擷取值為基礎的動作。