如何在drop上获取目标ListView项?

时间:2017-09-05 02:25:06

标签: c# listview uwp

在UWP C#中,我在上排有一个ListView&下排的另一个。当我从上面的ListView&中拖出一个listitem时把它放在较低的ListView上,我得到了源代码。但是,我无法到达目的地。 ie)我放弃的listview项目/(在我的情况下是Folder对象)。

<ListView Name="ListviewCars" 
            CanDragItems="True" DragItemsStarting="ListviewCars_DragItemsStarting"     
            SelectionMode="Single" IsItemClickEnabled="True"
            DataContext="Cars"  ItemsSource="{Binding CarsCollection}">

            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel  Background="Transparent"  Height="80" Orientation="Horizontal" 
                      HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"  />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

            <ListView.ItemTemplate >
                <DataTemplate>
                    <Grid Name="GrdCars" >
                        <Grid Height="80" Width="90" Padding="5">
                            <Grid.Background>
                                <ImageBrush Stretch="Uniform" ImageSource="Assets/car.png"/>
                            </Grid.Background>
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" TextWrapping="Wrap" TextAlignment="Center" 
                                              HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>                        
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>



        <ListView Name="GrdViewImg"  ScrollViewer.VerticalScrollBarVisibility="Disabled"
            AllowDrop="True" DragOver="Image_DragOver" 
            Drop="Image_OnDrop"
            DataContext="Folders"  ItemsSource="{Binding FolderCollection}">

            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Background="Transparent"  Height="80" Orientation="Horizontal" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"  />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

            <ListView.ItemTemplate >
                <DataTemplate>
                    <Grid Name="GrdForFolderMenu" RightTapped="GrdForFolderMenu_RightTapped">
                        <Grid Height="80" Width="90" Padding="5">
                            <Grid.Background>
                                <ImageBrush Stretch="UniformToFill" ImageSource="Assets/Folderimage.png"/>
                            </Grid.Background>
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" TextWrapping="Wrap" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>                       
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

3 个答案:

答案 0 :(得分:2)

I have found a simple solution myself. I get the source from DragItemsStarting event of the SoureListView. and target item (as mentioned by ashchuk) from a Grid placed inside Datatemplate of Target ListView. as shown below. Everything works fine now! (Cars is my Source custom list item. Folders is my Target custom list item)

    private void SoureListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        Cars x = e.Items[0] as Cars;
        string DraggedSourceCar = x.Name;
        e.Data.Properties.Add("myArgs", DraggedSourceCar);
    }

    private void GridInsideDatatemplateOfTargetListview_Drop(object sender, DragEventArgs e)
    {
        var x = sender as Grid;
        var y = x.DataContext as Folders;
        string toMoveFolderName = y.Name;

        string DraggedSourceCar = e.DataView.Properties["myArgs"].ToString();
        Debug.WriteLine(DraggedSourceCar + Environment.NewLine + toMoveFolderName );
    }

    private void TargetListview_DragOver(object sender, DragEventArgs e)
    {
        e.AcceptedOperation = DataPackageOperation.Copy;
    }

答案 1 :(得分:0)

您检查了this样本吗? 经过一些研究后,我发现当DragEventArgs事件被调用时,OriginalSource包含Name属性,Drop匹配目标列表的名称。

我没有用文件夹和子文件夹检查它,但是OriginalSource可能包含丢弃项目的文件夹。

    <TextBlock Grid.Row="1" Margin="8,4"
        VerticalAlignment="Bottom"
        Text="All Items"/>

    <ListView x:Name="SourceListView"
        Grid.Row="2" Margin="8,4"
        SelectionMode="Extended"
        CanDragItems="True"
        DragItemsStarting="SourceListView_DragItemsStarting"/>

    <TextBlock Grid.Row="1" Grid.Column="1" Margin="8,4"
       VerticalAlignment="Bottom"
       Text="Selection"/>

    <ListView x:Name="TargetListView"
       Grid.Row="2" Grid.Column="1" Margin="8,4"
       AllowDrop="True" CanReorderItems="True" CanDragItems="True"
       DragOver="TargetListView_DragOver"
       Drop="TargetListView_Drop"
       DragItemsStarting="TargetListView_DragItemsStarting"
       DragItemsCompleted="TargetListView_DragItemsCompleted"/> 

这是带有断点的打印屏幕:

enter image description here

修改

要获取TargetList中的项目,您可以做一个技巧。

我认为您使用DataTemplate来显示自定义列表项(&#34;文件夹&#34;)。您可以在下面看到示例。如您所见,我添加了Grid_DragOver触发器。

<Page.Resources>
    <DataTemplate x:Key="ListViewDataTemplate">
        <Grid Margin="20,5" DragOver="Grid_DragOver" 
              BorderBrush="White" BorderThickness="5" AllowDrop="True">
            <TextBlock Margin="10" LineHeight="40" FontSize="32" FontWeight="Bold"/>
        </Grid>
    </DataTemplate>
</Page.Resources>

当鼠标指针进入Grid_DragOver中的Grid时,将调用DataTemplate。 如果您使用绑定List<YourFolderClass>作为数据源,则您将在DataContext中获取文件夹。例如,我使用了这个:

var SampleData = new ObservableCollection<string>
            {
                "My Research Paper",
                "Electricity Bill",
                "My To-do list",
                "TV sales receipt",
                "Water Bill",
                "Grocery List",
                "Superbowl schedule",
                "World Cup E-ticket"
            };

enter image description here

您可以在gist中看到所有代码。

答案 2 :(得分:0)

你必须自己找出目的地drop中的DragEventArgs.GetPosition(),然后找到带有smoe辅助函数的基础项

public static object GetObjectAtPoint<ItemContainer>(this ItemsControl control, Point p)
                                     where ItemContainer : DependencyObject
        {
            // ItemContainer - can be ListViewItem, or TreeViewItem and so on(depends on control) 
            ItemContainer obj = GetContainerAtPoint<ItemContainer>(control, p);
            if (obj == null)
                return null;

            return control.ItemContainerGenerator.ItemFromContainer(obj);
        }

        public static ItemContainer GetContainerAtPoint<ItemContainer>(this ItemsControl control, Point p)
                                 where ItemContainer : DependencyObject
        {
            HitTestResult result = VisualTreeHelper.HitTest(control, p);
            if (result != null)
            {
                DependencyObject obj = result.VisualHit;

                while (VisualTreeHelper.GetParent(obj) != null && !(obj is ItemContainer))
                {
                    obj = VisualTreeHelper.GetParent(obj);
                }

                // Will return null if not found 
                return obj as ItemContainer;
            }
            else return null;
        }