249*_*076 6 c# wpf treeview wpf-controls
我试图制作一个非常简单的,或者我认为,程序将文件从桌面/资源管理器拖放到wpf树视图上.
这个例子中的树视图很简单,所以我可以隔离我遇到的拖放问题.我已将AllowDrop设置为整个地方的True,我仍然无法触发Drop或DragOver事件.我专注于树视图控件,因为我希望能够将文件拖动到具有分层结构的不同节点中. 现在,当我将文件拖到树视图上时,我会满足于能够触发DragOver或Drop事件.
我通过查看这样的示例开始:在Treeview中拖放
我的问题与此类似:将浏览器中的文件拖放到Telerik WPF树视图中.但是我使用的是wpf treeview,而不是telerik.
这是我到目前为止的代码
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>
Run Code Online (Sandbox Code Playgroud)
码:
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
编辑 我加粗了解释我的问题的文本,因为事件没有解雇.
我将我的xaml切换到了这个,当我在树视图上拖动文件时,我仍然会得到一个带有一条直线的黑色圆圈,唯一的事件就是MouseMove.如果我使用鼠标执行这些操作,则不会触发拖放.
<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>
Run Code Online (Sandbox Code Playgroud)
编辑 我尝试了一个空白的树视图,并能够在其上拖动一个文件,光标不是黑色圆圈,通过它的线条.
<TreeView Height="312" Background="#FFCFDBF9" AllowDrop="True"/>
Run Code Online (Sandbox Code Playgroud)
然而,当添加DataTemplate时,就是黑色圆圈开始出现的时候.这必须是某种数据绑定问题?
编辑 我现在开始到某个地方.
我将我的xaml更改为this并且事件开始触发:
<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>
Run Code Online (Sandbox Code Playgroud)
编辑 我发现如果我从表达式混合运行项目,我只能拖放到stackpanel.如果我从visual studio运行它,它会显示黑色圆圈,并在其中显示一条直线.这根本没有任何意义. 对于这个单独的问题,我在这里开始了另一个问题: 在调试或重新运行的Visual Studio 2010 WPF项目将不允许拖放到任何控件
这都是因为以管理员身份运行visual studio.显然,对于notepad.exe也是如此,如果您以管理员身份运行某些内容,则无法拖放.所以现在对于IIS调试我必须以管理员身份运行并且拖放我需要弄清楚如何在正常模式下运行...
我认为问题是您没有将项目拖动到 TreeViewItems 本身上。这是必要的,因为您的事件仅为 TreeViewItems 注册。如果您想拖放到树的父级别,则需要将相应的事件添加到树中。
此解决方案的问题是 TreeView 事件将首先触发。所以现在你必须知道你在哪个节点才能正确添加它。有一些解决方案可以确定您所在的节点。但是,我建议向您的树中添加一个始终存在的顶级元素。然后像您一样将事件连接到 TreeViewItems。这样,您就可以在顶层添加,而不必处理 TreeView 事件,因为您可以拖动到该顶层项目。
下面是我用来测试它的内容,如果我直接拖动到 TreeViewItems 上,我会看到断点。您可能无法识别某些名称空间,但那是因为它引用了我的项目。
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>
Run Code Online (Sandbox Code Playgroud)
背后代码:
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)
{
}
Run Code Online (Sandbox Code Playgroud)