无法将 AllowDrop、CanDragItems、CanReorderItems 属性添加到 Gridview

Can't add AllowDrop, CanDragItems, CanReorderItems properties to Gridview

作为练习,我正在尝试制作一个基本的浏览器。

我已经成功地将文件和/或(多个)文件夹拖放到我的资源管理器中,但希望能够在 GridView 中拖放。 主要是将文件重新排序或拖动到视图中的文件夹中。

在几次搜索中,我发现,首先,我应该将以下属性添加到我的 GridView 中:

CanReorderItems="True"
AllowDrop="True"
CanDragItems="True"

但是 VS 给我以下错误:

未在类型 'GridView' 中找到 属性 'CanDragItems'。

我见过多个将这些属性添加到 GridView 的示例。 我一定是遗漏了一些明显的东西。

我的XAML代码如下:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title=""
        Height="350"
        Width="525"
        MinHeight="200"
        MinWidth="200">
    <Grid>
        <Grid   AllowDrop="True"
                Drop="Grid_Drop">
            <Grid.RowDefinitions>
                <RowDefinition Height="26" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <ToolBar Grid.Row="0"
                     Grid.Column="0"
                     HorizontalAlignment="Stretch"
                     Name="toolBar1"
                     VerticalAlignment="Stretch">
                <Button  HorizontalAlignment="Left"
                         Name="btnFolderUp"
                         VerticalAlignment="Stretch"
                         Click="btnFolderUp_Click">
                    <Image Source="images\folder-up.png" />
                </Button>
                <Button  HorizontalAlignment="Left"
                         Name="btnFolderNew"
                         VerticalAlignment="Stretch"
                         Click="btnFolderNew_Click">
                    <Image Source="images\folder-new.png" />
                </Button>
            </ToolBar>
            <ListView Grid.Row="1"
                      Grid.Column="0"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      Name="lvDataBinding"
                      MouseDoubleClick="lvDataBinding_MouseDoubleClick">
                <ListView.View>
                    <GridView CanReorderItems="True"
                              AllowDrop="True"
                              CanDragItems="True">
                        <GridView.Columns>
                            <GridViewColumn>
                                <GridViewColumnHeader Content="Name"
                                                      Name="Name"
                                                      Click="GridViewColumnHeader_Click" />
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <Image Source="{Binding Path=fileIcon}"
                                                   Margin="3,3,3,3"
                                                   Width="15"
                                                   Height="15" />
                                            <TextBlock Text="{Binding Path=Name}"
                                                       HorizontalAlignment="Stretch"
                                                       VerticalAlignment="Stretch" />
                                        </StackPanel>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn>
                                <GridViewColumnHeader Content="DateCreated"
                                                      Name="DateCreated"
                                                      Click="GridViewColumnHeader_Click" />
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Path=DateCreated}"
                                                       HorizontalAlignment="Stretch"
                                                       VerticalAlignment="Stretch" />
                                        </StackPanel>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
        </Grid>
    </Grid>
</Window>

WPF version of GridView does not have those properties. But the WinRT/Universal version 确实如此。您看到的示例可能指的是 WinRT 版本。两个版本都有相似的成员,所以很容易混淆两者。

问题与 WPF 有关。
所以 ListView 上只存在 AllowDrop="true"。

为了支持拖放:

  1. 必须更改 ListView 项的样式:

       <Window.Resources>
        <Style x:Key="ListViewItemStyle1" TargetType="{x:Type ListViewItem}">
            <EventSetter Event="ListBoxItem.DragOver" Handler="ListBoxItemDragOver"/>
            <EventSetter Event="ListBoxItem.Drop" Handler="ListBoxItemDrop"/>
            <EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="ListBoxItemPreviewMouseMove"/>
        </Style>
    </Window.Resources>
    

在 ListView 声明中,引用样式:

        <ListView AllowDrop="True"
                  ItemContainerStyle="{DynamicResource ListViewItemStyle1}"
                  Name="lvDataBinding"
                  Drop="lvDataBinding_Drop"
                  DragOver="lvDataBinding_DragOver"
                  DragEnter="lvDataBinding_DragEnter">
  1. 必须执行 ListViewItems 的事件:

    private FileData sourceFileData;
    private void ListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton != MouseButtonState.Pressed)
            return;
        var listboxItem = sender as ListBoxItem;
        if (listboxItem == null)
            return;
        sourceFileData = listboxItem.DataContext as FileData;
        if (sourceFileData == null)
            return;
        var data = new DataObject();
        data.SetData(sourceFileData);
        // provide some data for DnD in other applications (Word, ...)
        data.SetData(DataFormats.StringFormat, sourceFileData.ToString());
        DragDropEffects effect = DragDrop.DoDragDrop(listboxItem, data, DragDropEffects.Move | DragDropEffects.Copy);
    }
    private void ListBoxItemDrop(object sender, DragEventArgs e)
    {
        // support application data source and explorer file
        if (!e.Data.GetDataPresent(typeof(FileData)) && !e.Data.GetDataPresent(DataFormats.FileDrop))
            return;
        var listBoxItem = sender as ListBoxItem;
        if (listBoxItem == null)
            return;
        var targetFile = listBoxItem.DataContext as FileData;
        if (targetFile != null)
        {
            int targetIndex = files.IndexOf(targetFile);
            int sourceIndex = files.IndexOf(sourceFileData);
            double y = e.GetPosition(listBoxItem).Y;
            bool insertAfter = y > listBoxItem.ActualHeight / 2;
            if (insertAfter)
            {
                targetIndex++;
            }
            if (sourceIndex > targetIndex)
            {
                if (sourceIndex != -1)
                    files.RemoveAt(sourceIndex);
                files.Insert(targetIndex, sourceFileData);
            }
            else
            {
                files.Insert(targetIndex, sourceFileData);
                if (sourceIndex != -1)
                    files.RemoveAt(sourceIndex);
            }
        }
        e.Handled = true;
    }
    private void ListBoxItemDragOver(object sender, DragEventArgs e)
    {
        Debug.WriteLine(e.Effects);
        if (!e.Data.GetDataPresent(typeof(FileData)) && !e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;
        }
    }
    
  2. 必须实现一些事件以允许来自外部应用程序(如 Explorer)的 DnD:

    private void lvDataBinding_DragOver(object sender, DragEventArgs e)
    {
        e.Handled = true;
    }
    private void lvDataBinding_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            String[] files =  e.Data.GetData(DataFormats.FileDrop) as String[];
            // that version only supports drop of a file, but could be augmented
            FileInfo fileInfo = new FileInfo(files[0]);
            sourceFileData = new FileData { DateCreated = fileInfo.CreationTime, Name = fileInfo.FullName };
            e.Handled = true;
        }
    }
    
  3. 以上代码均为window.
    的代码 但是数据可能来自一个不错的项目中的视图模型。
    这是数据的初始化:

    public 部分 class 主要Window : Window {

    private ObservableCollection<FileData> files;
    public MainWindow()
    {
        files = new ObservableCollection<FileData>(
        new DirectoryInfo(@"e:\temp")
            .EnumerateFiles()
            .Select(fi => new FileData { DateCreated = fi.CreationTime, Name = fi.FullName })
        );
        InitializeComponent();
        lvDataBinding.ItemsSource = files;
    }  
    

这是一个显示代码的有效 VS 解决方案:
http://1drv.ms/1FNsK7n

此致