南宁工程建设网站有哪些,绿化公司网站建设,网站 侧边栏,安徽天长建设局网站文章目录 创建可拖放控件创建绑定服务类拖拽#xff08;Drag#xff09;拖拽悬停#xff0c;经过#xff08;DragOver#xff09;释放#xff08;Drop#xff09; 创建页面元素最终效果项目地址 .NET MAUI 中提供了拖放(drag-drop)手势识别器#xff0c;允许用户通过拖… 文章目录 创建可拖放控件创建绑定服务类拖拽Drag拖拽悬停经过DragOver释放Drop 创建页面元素最终效果项目地址 .NET MAUI 中提供了拖放(drag-drop)手势识别器允许用户通过拖动手势来移动控件。在这篇文章中我们将学习如何使用拖放手势识别器来实现可拖拽排序列表。在本例中列表中显示不同大小的磁贴Tile并且可以拖拽排序。 使用.NET MAU实现跨平台支持本项目可运行于Android、iOS平台。
创建可拖放控件
新建.NET MAUI项目命名Tile
当手指触碰可拖拽区域超过一定时长不同平台下时长不一定相同如在Android中是1s时将触发拖动手势。 手指离开屏幕时将触发放置手势。
启用拖动
为页面视图控件创建拖动手势识别器(DragGestureRecognizer) 它定义了以下属性
属性类型描述CanDragbool指明手势识别器附加到的控件能否为拖动源。 此属性的默认值为 true。CanDragbool指明手势识别器附加到的控件能否为拖动源。 此属性的默认值为 true。DragStartingCommandICommand在第一次识别拖动手势时执行。DragStartingCommandParameterobject是传递给 DragStartingCommand 的参数。DropCompletedCommandICommand在放置拖动源时执行。DropCompletedCommandParameterobject是传递给 DropCompletedCommand 的参数。
启用放置
为页面视图控件创建放置手势识别器(DropGestureRecognizer) 它定义了以下属性
属性类型描述AllowDropbool指明手势识别器附加到的元素能否为放置目标。 此属性的默认值为 true。DragOverCommandICommand在拖动源被拖动到放置目标上时执行。DragOverCommandParameterobject是传递给 DragOverCommand 的参数。DragLeaveCommandICommand在拖动源被拖至放置目标上时执行。DragLeaveCommandParameterobject是传递给 DragLeaveCommand 的参数。DropCommandICommand在拖动源被放置到放置目标上时执行。DropCommandParameterobject是传递给 DropCommand 的参数。
创建可拖拽控件的绑定类实现IDraggableItem接口定义拖动相关的属性和命令。
public interface IDraggableItem
{bool IsBeingDraggedOver { get; set; }bool IsBeingDragged { get; set; }Command Dragged { get; set; }Command DraggedOver { get; set; }Command DragLeave { get; set; }Command Dropped { get; set; }object DraggedItem { get; set; }object DropPlaceHolderItem { get; set; }
}
Dragged 拖拽开始时触发的命令。 DraggedOver 拖拽控件悬停在当前控件上方时触发的命令。 DragLeave 拖拽控件离开当前控件时触发的命令。 Dropped 拖拽控件放置在当前控件上方时触发的命令。
IsBeingDragged 为true时通知当前控件正在被拖拽。 IsBeingDraggedOver 为true时通知当前控件正在有拖拽控件悬停在其上方。
DraggedItem 正在拖拽的控件。 DropPlaceHolderItem 悬停在其上方时的控件即当前控件的占位控件。
此时可拖拽控件为磁贴片段TileSegement 创建一个类用于描述磁贴可显示的属性如标题、描述、图标、颜色等。
public class TileSegment
{public string Title { get; set; }public string Type { get; set; }public string Desc { get; set; }public string Icon { get; set; }public Color Color { get; set; }
}创建绑定服务类
创建可拖拽控件的绑定服务类TileSegmentService继承ObservableObject并实现IDraggableItem接口。
public class TileSegmentService : ObservableObject, ITileSegmentService
{...
}
拖拽Drag
拖拽开始时将IsBeingDragged设置为true通知当前控件正在被拖拽同时将DraggedItem设置为当前控件。
private void OnDragged(object item)
{IsBeingDraggedtrue;DraggedItemitem;
}
拖拽悬停经过DragOver
拖拽控件悬停在当前控件上方时将IsBeingDraggedOver设置为true通知当前控件正在有拖拽控件悬停在其上方同时在服务列表中寻找当前正在被拖拽的服务将DropPlaceHolderItem设置为当前控件。
private void OnDraggedOver(object item)
{if (!IsBeingDragged item!null){IsBeingDraggedOvertrue;var itemToMove Container.TileSegments.First(i i.IsBeingDragged);if (itemToMove.DraggedItem!null){DropPlaceHolderItemitemToMove.DraggedItem;}}}
离开控件上方时IsBeingDraggedOver设置为false
private void OnDragLeave(object item)
{IsBeingDraggedOver false;
}释放Drop
拖拽完成时获取当前正在被拖拽的控件将其从服务列表中移除然后将其插入到当前控件的位置通知当前控件拖拽完成。
private void OnDropped(object item)
{var itemToMove Container.TileSegments.First(i i.IsBeingDragged);if (itemToMove null || itemToMove this)return;Container.TileSegments.Remove(itemToMove);var insertAtIndex Container.TileSegments.IndexOf(this);Container.TileSegments.Insert(insertAtIndex, itemToMove);itemToMove.IsBeingDragged false;IsBeingDraggedOver false;DraggedItemnull;}完整的TileSegmentService代码如下
public class TileSegmentService : ObservableObject, ITileSegmentService
{public TileSegmentService(TileSegment tileSegment){Remove new Command(RemoveAction);TileSegment tileSegment;Dragged new Command(OnDragged);DraggedOver new Command(OnDraggedOver);DragLeave new Command(OnDragLeave);Dropped new Command(i OnDropped(i));}private void OnDragged(object item){IsBeingDraggedtrue;}private void OnDraggedOver(object item){if (!IsBeingDragged item!null){IsBeingDraggedOvertrue;var itemToMove Container.TileSegments.First(i i.IsBeingDragged);if (itemToMove.DraggedItem!null){DropPlaceHolderItemitemToMove.DraggedItem;}}}private object _draggedItem;public object DraggedItem{get { return _draggedItem; }set{_draggedItem value;OnPropertyChanged();}}private object _dropPlaceHolderItem;public object DropPlaceHolderItem{get { return _dropPlaceHolderItem; }set{_dropPlaceHolderItem value;OnPropertyChanged();}}private void OnDragLeave(object item){IsBeingDraggedOver false;DraggedItem null;}private void OnDropped(object item){var itemToMove Container.TileSegments.First(i i.IsBeingDragged);if (itemToMove null || itemToMove this)return;Container.TileSegments.Remove(itemToMove);var insertAtIndex Container.TileSegments.IndexOf(this);Container.TileSegments.Insert(insertAtIndex, itemToMove);itemToMove.IsBeingDragged false;IsBeingDraggedOver false;DraggedItemnull;}private async void RemoveAction(object obj){if (Container is ITileSegmentServiceContainer){(Container as ITileSegmentServiceContainer).RemoveSegment.Execute(this);}}public IReadOnlyTileSegmentServiceContainer Container { get; set; }private TileSegment tileSegment;public TileSegment TileSegment{get { return tileSegment; }set{tileSegment value;OnPropertyChanged();}}private bool _isBeingDragged;public bool IsBeingDragged{get { return _isBeingDragged; }set{_isBeingDragged value;OnPropertyChanged();}}private bool _isBeingDraggedOver;public bool IsBeingDraggedOver{get { return _isBeingDraggedOver; }set{_isBeingDraggedOver value;OnPropertyChanged();}}public Command Remove { get; set; }public Command Dragged { get; set; }public Command DraggedOver { get; set; }public Command DragLeave { get; set; }public Command Dropped { get; set; }
}创建页面元素
在Controls目录下创建不同大小的磁贴控件如下图所示。 在MainPage中创建CollectionView用于将磁贴元素以列表形式展示。
CollectionView Grid.Row1x:NameMainCollectionViewItemsSource{Binding TileSegments}ItemTemplate{StaticResource TileSegmentDataTemplateSelector}CollectionView.ItemsLayoutLinearItemsLayout OrientationVertical //CollectionView.ItemsLayout
/CollectionView创建MainPageViewModel创建绑定服务类集合TileSegments初始化中添加一些不同颜色大小的磁贴并将TileSegementService.Container设置为自己(this)。
不同大小的磁贴通过绑定相应的数据使用不同的数据模板进行展示。请阅读博文 [MAUI程序设计]界面多态与实现了解如何实现列表Item的多态。 在MainPage中创建磁贴片段数据模板选择器TileSegmentDataTemplateSelector用于根据磁贴片段的大小选择不同的数据模板。
DataTemplate x:KeySmallSegmentcontrols1:SmallSegmentView Margin0,5ControlTemplate{StaticResource TileSegmentTemplate}/controls1:SmallSegmentView
/DataTemplate
DataTemplate x:KeyMediumSegmentcontrols1:MediumSegmentView Margin0,5ControlTemplate{StaticResource TileSegmentTemplate}/controls1:MediumSegmentView
/DataTemplate
DataTemplate x:KeyLargeSegmentcontrols1:LargeSegmentView Margin0,5ControlTemplate{StaticResource TileSegmentTemplate}/controls1:LargeSegmentView
/DataTemplate
controls1:TileSegmentDataTemplateSelector x:KeyTileSegmentDataTemplateSelectorResourcesContainer{x:Reference Main} /创建磁贴控件模板TileSegmentTemplate并在此指定DropGestureRecognizer
ControlTemplate x:KeyTileSegmentTemplateContentViewStackLayoutStackLayout.GestureRecognizersDropGestureRecognizer AllowDropTrueDragLeaveCommand{TemplateBinding BindingContext.DragLeave}DragLeaveCommandParameter{TemplateBinding}DragOverCommand{TemplateBinding BindingContext.DraggedOver}DragOverCommandParameter{TemplateBinding}DropCommand{TemplateBinding BindingContext.Dropped}DropCommandParameter{TemplateBinding} //StackLayout.GestureRecognizers/StackLayout/ContentView
/ControlTemplate
创建磁贴控件外观LayoutContentPresenter /处将呈现磁贴片段的内容。在Layout指定DragGestureRecognizer。
Border x:NameContentLayoutMargin0GridGrid.GestureRecognizersDragGestureRecognizer CanDragTrueDragStartingCommand{TemplateBinding BindingContext.Dragged}DragStartingCommandParameter{TemplateBinding} //Grid.GestureRecognizersContentPresenter /Button CornerRadius100HeightRequest20WidthRequest20Padding0BackgroundColorRedTextColorWhiteCommand{TemplateBinding BindingContext.Remove}Text×HorizontalOptionsEndVerticalOptionsStart/Button/Grid
/Border 创建占位控件用于指示松开手指时控件将放置的位置区域在这里绑定DropPlaceHolderItem的高度和宽度。
Border StrokeThickness4StrokeDashArray2 2StrokeDashOffset6StrokeblackHorizontalOptionsCenterIsVisible{TemplateBinding BindingContext.IsBeingDraggedOver}Grid HeightRequest{TemplateBinding BindingContext.DropPlaceHolderItem.Height}WidthRequest{TemplateBinding BindingContext.DropPlaceHolderItem.Width}Label HorizontalTextAlignmentCenterVerticalOptionsCenterText松开手指将放置条目至此处/Label/Grid
/Border
最终效果 项目地址
Github:maui-samples
关注我学习更多.NET MAUI开发知识