You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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为目标容器
    initial state
  • 选中上方CollectionView的第一个项
    first item selected
  • 选中上方CollectionView的第二个项
    first and second items selected
  • 按住第一个选中项开始拖拽
    drag start
  • 期望实现的拖拽效果
    expected result

补充提问

目前已找到UWP平台的相关API Windows.UI.Xaml.DragEventArgs.DragUIOverride可实现自定义拖拽UI,但它仅适用于UWP平台,请问Android/iOS平台有没有对应的等效实现?


内容的提问来源于stack exchange,提问作者Simon Mardiné

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:15:03