Xamarin.Forms 5.0 CollectionView多选拖拽如何显示所有选中项的拖拽外观
Xamarin.Forms CollectionView多选拖拽时显示所有选中项外观问题
我在Xamarin.Forms 5.0中使用CollectionView控件,已经通过设置SelectionMode="Multiple"实现了同窗口下两个CollectionView之间的多选项迁移功能。测试用例是基于网上的开源示例自定义修改的。
现在遇到的问题和拖拽项的外观有关:
我在第一个CollectionView的CollectionView.ItemTemplate.DataTemplate中添加了DragGestureRecognizer,在第二个CollectionView的对应模板中添加了DropGestureRecognizer,拖拽功能本身运行正常,但拖拽动画仅显示我当前触摸的那一个选项,不会展示所有已选中的待拖拽项。
请问有没有方案可以实现这个需求?该需求是否可行?
XAML页面代码
<?xml version="1.0" encoding="UTF-8" ?> <ContentPage x:Class="DragAndDropXFSample.EventsPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <ContentPage.Content> <StackLayout Padding="20,40" BackgroundColor="Black"> <Label FontAttributes="Bold" FontSize="Large" Text="Hi John" /> <Label Text="Your schedule Today" /> <Frame Margin="0,20,0,0" BackgroundColor="White"> <StackLayout> <CollectionView x:Name="EventsCollection" ItemsSource="{Binding Events}" SelectionMode="Multiple"> <CollectionView.EmptyView> <Label Text="You have no events" VerticalOptions="CenterAndExpand" /> </CollectionView.EmptyView> <CollectionView.ItemsLayout> <GridItemsLayout HorizontalItemSpacing="10" Orientation="Vertical" Span="2" VerticalItemSpacing="10" /> </CollectionView.ItemsLayout> <CollectionView.ItemTemplate> <DataTemplate> <Frame Padding="0" BackgroundColor="{Binding Color}" HasShadow="False"> <Frame.Style> <Style TargetType="Frame"> <!-- 向用户可视化展示选中状态 --> <Setter Property="VisualStateManager.VisualStateGroups"> <VisualStateGroupList> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="CadetBlue" /> <Setter TargetName="uiTime" Property="Label.FontAttributes" Value="Italic" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </Setter> </Style> </Frame.Style> <StackLayout Padding="10,10,10,0" Spacing="10"> <Label x:Name="uiTime" FontAttributes="Bold" FontSize="Large" Text="{Binding Time, StringFormat='{0:HH:mm}'}" /> <Label FontSize="15" Text="{Binding Title}" /> <Label FontSize="Caption" Text="{Binding Location, StringFormat='At {0}'}" TextColor="White" /> <StackLayout Margin="-10,0" Padding="5" BackgroundColor="#66000000" Orientation="Horizontal"> <Image HeightRequest="20" HorizontalOptions="EndAndExpand" Source="ic_edit" /> <Label FontSize="Caption" Text="Edit" TextColor="White" VerticalOptions="Center" /> </StackLayout> </StackLayout> <Frame.GestureRecognizers> <DragGestureRecognizer DragStartingCommand="{Binding Path=BindingContext.DragStartingCommand, Source={x:Reference EventsCollection}}" DragStartingCommandParameter="{Binding SelectedItems, Source={x:Reference EventsCollection}}" /> </Frame.GestureRecognizers> </Frame> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <CollectionView x:Name="EventsCollection2" ItemsSource="{Binding Events2}"> <CollectionView.EmptyView> <Label Text="You have no events" VerticalOptions="CenterAndExpand" /> </CollectionView.EmptyView> <CollectionView.ItemsLayout> <GridItemsLayout HorizontalItemSpacing="10" Orientation="Vertical" Span="2" VerticalItemSpacing="10" /> </CollectionView.ItemsLayout> <CollectionView.ItemTemplate> <DataTemplate> <Frame Padding="0" BackgroundColor="{Binding Color}" HasShadow="False"> <StackLayout Padding="10,10,10,0" Spacing="10"> <Label x:Name="uiTime2" FontAttributes="Bold" FontSize="Large" Text="{Binding Time, StringFormat='{0:HH:mm}'}" /> <Label FontSize="15" Text="{Binding Title}" /> <Label FontSize="Caption" Text="{Binding Location, StringFormat='At {0}'}" TextColor="White" /> <StackLayout Margin="-10,0" Padding="5" BackgroundColor="#66000000" Orientation="Horizontal"> <Image HeightRequest="20" HorizontalOptions="EndAndExpand" Source="ic_edit" /> <Label FontSize="Caption" Text="Edit" TextColor="White" VerticalOptions="Center" /> </StackLayout> </StackLayout> <Frame.GestureRecognizers> <DropGestureRecognizer DropCommand="{Binding BindingContext.DropOverList2Command, Source={x:Reference EventsCollection2}}" /> </Frame.GestureRecognizers> </Frame> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </Frame> </StackLayout> </ContentPage.Content> </ContentPage>
视图模型类代码
public class EventsPageViewModel { private IList<Event> _dragEvent; /// <summary> /// 由于使用了Selectionmode.Multiple,所以命令类型为Command<IList<object>> /// </summary> public ICommand DragStartingCommand => new Command<IList<object>>((param) => { _dragEvent = new List<Event>(param.Cast<Event>()); }); public ICommand DropOverList2Command => new Command(() => { foreach (var e in _dragEvent) { if (Events.Contains(e)) { Events.Remove(e); Events2.Add(e); } } }); public ObservableCollection<Event> Events { get; } public ObservableCollection<Event> Events2 { get; } public EventsPageViewModel() { Events = new ObservableCollection<Event>() { {new Event("Go for a walk", "Home", DateTime.Now.AddHours(3), Color.OrangeRed) }, {new Event("Finish PR", "Work", DateTime.Now.AddHours(5), Color.ForestGreen) }, {new Event("Watch a movie", "Home", DateTime.Now.AddMinutes(40), Color.LightSkyBlue) }, }; Events2 = new ObservableCollection<Event>() { {new Event("Go for a walk2", "Home", DateTime.Now.AddHours(3), Color.GreenYellow) } }; } }
补充说明
效果演示截图
- 初始状态:无选中项,上方CollectionView为拖拽源,下方CollectionView为目标容器

- 选中上方CollectionView的第一个项

- 选中上方CollectionView的第二个项

- 按住第一个选中项开始拖拽

- 期望实现的拖拽效果

补充提问
目前已找到UWP平台的相关API Windows.UI.Xaml.DragEventArgs.DragUIOverride可实现自定义拖拽UI,但它仅适用于UWP平台,请问Android/iOS平台有没有对应的等效实现?
内容的提问来源于stack exchange,提问作者Simon Mardiné
相关产品推荐
相关产品推荐

