WPF 从 Windows 资源管理器中将文件拖放到 TreeView 上 [英] WPF drag and drop files onto TreeView from windows explorer

查看:33
本文介绍了WPF 从 Windows 资源管理器中将文件拖放到 TreeView 上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个非常简单的程序,或者我认为,将文件从桌面/资源管理器拖放到 wpf 树视图上的程序.

I am trying to make an extremely simple, or so I thought, program to drag and drop a file from the desktop/explorer onto a wpf treeview.

此示例中的树视图很简单,因此我可以隔离遇到的拖放问题.我在所有地方都设置了 AllowDrop 等于 True,但我仍然无法触发 Drop 或 DragOver 事件.我专注于树视图控件,因为我希望能够将文件拖动到具有层次结构的不同节点中.现在,当我将文件拖到树视图上时,我会满足于能够触发 DragOver 或 Drop 事件.

The treeview in this example is simple so that I could isolate the drag and drop problem I am having. I have set AllowDrop equals True all over the place, I still can't get the Drop or DragOver events to fire. I am focused on a treeview control because I want to be able to drag files into different nodes with a hierarchical structure. Right now I would settle for just being able to get the DragOver or Drop events to fire when I drag a file onto the treeview.

我是通过查看这样的示例开始的:Drag &放入树状视图

I have gotten started by looking at examples such as this: Drag & Drop in Treeview

我的问题与此类似:拖放文件从资源管理器到 Telerik WPF 树视图.但是我使用的是 wpf 树视图,而不是 Telerik 的.

My question is similiar to this one: Drag drop files from explorer onto Telerik WPF treeview. However I am using the wpf treeview, not the telerik one.

这是我目前的代码

XAML:

   <Window x:Class="WpfDragAndDropTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfDragAndDropTest"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView Name="TreeView1">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" >
                    <Setter Property="TreeViewItem.AllowDrop" Value="True"/>
                    <EventSetter Event="TreeViewItem.DragOver" Handler="TreeView1_DragOver" />
                    <EventSetter Event="TreeViewItem.Drop" Handler="TreeView1_Drop" />
                    <EventSetter Event="TreeViewItem.MouseMove" Handler="TreeView1_MouseMove" />
                </Style>
            </TreeView.ItemContainerStyle>

            <TreeView.Resources>
                <DataTemplate DataType="{x:Type local:TestClass}">
                    <StackPanel Orientation="Vertical"  >
                        <TextBlock Text="{Binding Path=Title}" />
                        <TextBlock Text="{Binding Path=Url}" />
                    </StackPanel>
                </DataTemplate>
            </TreeView.Resources>

        </TreeView>
    </Grid>
    </Window>

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfDragAndDropTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        TreeView1.ItemsSource = new[] 
        { 
            new TestClass { Title = "Google", Url = "http://www.google.com" }, 
            new TestClass { Title = "Microsoft", Url = "http://www.microsoft.com" },
            new TestClass{ Title="Netflix", Url="http://www.netflix.com" }
        };
    }

    private void TreeView1_Drop(object sender, DragEventArgs e)
    {

    }

    private void TreeView1_DragOver(object sender, DragEventArgs e)
    {

    }

    private void TreeView1_MouseMove(object sender, MouseEventArgs e)
    {

    }
}


public class TestClass
{
    public string Title { get; set; }
    public string Url { get; set; }
}
}

编辑我将说明我的问题的文本加粗,因为事件没有触发.

Edit I bolded the text that spells out my problem as the events not firing.

我将我的 xaml 切换到这个,当在树视图上拖动文件时,我仍然得到一个带有一条线的黑色圆圈,并且触发的唯一事件是 MouseMove.如果我使用鼠标执行这些操作,则不会触发拖放.

I switched my xaml to this and I still get a black circle with a line through it when dragging a file over the treeview and the only event that fires is the MouseMove. The Drag and Drop do not fire if I use the mouse to perform those actions.

    <TreeView Name="TreeView1" AllowDrop="True" DragOver="TreeView1_DragOver" Drop="TreeView1_Drop" MouseMove="TreeView1_MouseMove">


        <TreeView.Resources>
            <DataTemplate DataType="{x:Type local:TestClass}">
                <StackPanel Orientation="Vertical"  >
                    <TextBlock Text="{Binding Path=Title}" />
                    <TextBlock Text="{Binding Path=Url}" />
                </StackPanel>
            </DataTemplate>
        </TreeView.Resources>

    </TreeView>

编辑我尝试了一个空白的树状视图,并且能够将一个文件拖到它上面,但光标不是带有穿过它的线的黑色圆圈.

Edit I tried a blank treeview and was able to drag a file over it, and the cursor was not the black circle with the line through it.

<TreeView Height="312" Background="#FFCFDBF9" AllowDrop="True"/>

但是,当该 DataTemplate 添加到其中时,黑色圆圈开始出现.这一定是某种数据绑定问题?

However when that DataTemplate is added to it, that's when the black circle starts showing up. This must be some kind of databinding issue?

编辑我现在开始到达某个地方了.

Edit I'm starting to get somewhere now.

我将我的 xaml 更改为此,事件开始触发:

I changed my xaml to this and the events start firing:

<TreeView Name="TreeView1" Background="#FFC9D7FF">


    <TreeView.Resources>
        <DataTemplate DataType="{x:Type local:TestClass}">
            <StackPanel Orientation="Vertical"  AllowDrop="True" DragOver="TreeView1_DragOver" Drop="TreeView1_Drop" MouseMove="TreeView1_MouseMove" >
                <TextBlock Text="{Binding Path=Title}" />
                <TextBlock Text="{Binding Path=Url}" />
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>

</TreeView>

编辑我发现如果我从表达式混合运行项目,我只能拖放到堆栈面板.如果我从 Visual Studio 运行它,它会显示黑色圆圈,并有一条线穿过它.这根本没有任何意义.对于这个单独的问题,我在这里提出了另一个问题: 在调试或发布中运行的 Visual Studio 2010 WPF 项目将不允许拖放到任何控件

edit I have discovered that I can only drag and drop to the stackpanel if I run the project from expression blend. If I run it from visual studio it shows the black circle with a line through it. That doesn't make any sense at all. For this seperate problem I have started another question here: Visual Studio 2010 WPF Project ran in debug or relase will not allow drag and drop to any control

这都是因为以管理员身份运行visual studio.notepad.exe 显然也是如此,如果您以管理员身份运行某些程序,则无法拖放.所以现在对于 IIS 调试,我必须以管理员身份运行,对于拖放,我需要弄清楚如何在正常模式下运行...

推荐答案

我认为问题在于您没有将项目拖到 TreeViewItems 本身上.这是必要的,因为您的事件仅为 TreeViewItems 注册.如果要拖放到树的父级别,则需要将相应的事件添加到树中.

I think the issue is you are not dragging the item over the TreeViewItems themselves. This is necessary because your events are registered for the TreeViewItems only. If you want to drag and drop into a parent level of you tree, you will need to add the corresponding events to your tree.

您在使用此解决方案时遇到的问题是 TreeView 事件将首先触发.所以现在你必须知道你结束了哪个节点才能正确添加它.有一些解决方案可以确定您在哪个节点上.但是,我建议向您的树中添加一个始终存在的顶级元素.然后像您一样将事件连接到 TreeViewItems.这样,您就可以在顶层添加,而无需处理 TreeView 事件,因为您可以拖动到该顶层项目.

The issue you will have with this solution is the TreeView events will fire first. So now you're going to have to know which node you're over to add it properly. There are solutions to figure out which node you are over. However, I would suggest adding a top level element to your tree that is always there. Then wire up the events to the TreeViewItems like you are. That way, you can add at a top level without having to handle the TreeView events because you can drag to that top level item.

下面是我用来测试它的内容,如果我直接拖到 TreeViewItems 上,我会看到断点.您可能不认识某些命名空间,但那是因为它引用了我的项目.

Below is what I used to test it out and I'm seeing the breakpoints if I drag directly over the TreeViewItems. You may not recognize some namespaces but that's because it's referencing my project.

XAML:

  <TreeView x:Name="treeView">
     <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}" >
           <Setter Property="TreeViewItem.AllowDrop" Value="True"/>
           <EventSetter Event="TreeViewItem.DragOver" Handler="treeView_DragOver" />
           <EventSetter Event="TreeViewItem.Drop" Handler="treeView_Drop" />
           <EventSetter Event="TreeViewItem.MouseMove" Handler="treeView_MouseMove" />
        </Style>
     </TreeView.ItemContainerStyle>

     <TreeView.Resources>
        <DataTemplate DataType="{x:Type FileExplorerDragDrop:TestClass}">
           <StackPanel Orientation="Vertical"  >
              <TextBlock Text="{Binding Path=Title}" />
              <TextBlock Text="{Binding Path=Url}" />
           </StackPanel>
        </DataTemplate>
     </TreeView.Resources>
  </TreeView>  

背后的代码:

  public MainWindow()
  {
     InitializeComponent();

     treeView.ItemsSource = new[] 
     { 
        new TestClass { Title = "Google", Url = "http://www.google.com" }, 
        new TestClass { Title = "Microsoft", Url = "http://www.microsoft.com" },
        new TestClass{ Title="Netflix", Url="http://www.netflix.com" }
     };
  }

  private void treeViewItem_DragOver(object sender, DragEventArgs e)
  {

  }

  private void treeViewItem_Drop(object sender, DragEventArgs e)
  {

  }

  private void treeViewItem_MouseMove(object sender, MouseEventArgs e)
  {

  }

这篇关于WPF 从 Windows 资源管理器中将文件拖放到 TreeView 上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆