2011-09-19 25 views
6

Estoy tratando de hacer un programa extremadamente simple, o al menos eso pensé, para arrastrar y soltar un archivo desde el escritorio/explorador en una vista de árbol wpf.WPF arrastrar y soltar archivos en TreeView desde el explorador de Windows

La vista de árbol en este ejemplo es simple para poder aislar el problema de arrastrar y soltar que tengo. Configuré que AllowDrop es igual a True en todos los lugares, todavía no puedo hacer que los eventos Drop o DragOver se disparen. Estoy enfocado en un control treeview porque quiero ser capaz de arrastrar archivos a diferentes nodos con una estructura jerárquica. Ahora me gustaría conformarme con solo poder hacer que los eventos DragOver o Drop se disparen cuando arrastro un archivo a la vista de árbol.

he hecho más que empezar mirando ejemplos como este: Drag & Drop in Treeview

Mi pregunta es similar a la siguiente: Drag drop files from explorer onto Telerik WPF treeview. Sin embargo, estoy usando la vista de árbol de wpf, no la de telerik.

Aquí está el código que tengo hasta ahora

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> 

Código:

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; } 
} 
} 

Editar I en negrita el texto que explique mi problema, ya que los eventos no disparando

Cambié mi xaml a esto y sigo teniendo un círculo negro con una línea al arrastrar un archivo sobre la vista de árbol y el único evento que se dispara es el MouseMove. El arrastrar y soltar no se dispara si uso el mouse para realizar esas acciones.

<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> 

Editar que intentaron una vista de árbol en blanco y era capaz de arrastrar un archivo sobre él, y el cursor no era el círculo negro con la línea a través de él.

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

Sin embargo, cuando se añade que DataTemplate a ella, que es cuando el círculo negro comienza a aparecer. Esto debe ser algún tipo de problema de enlace de datos?

Editar Estoy empezando a llegar a algún lado ahora.

he cambiado de xaml a esto y los acontecimientos empiezan a disparar:

<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> 

edición he descubierto que sólo puedo arrastrarlo a la StackPanel si funciono el proyecto de Expression Blend. Si lo ejecuto desde Visual Studio, muestra el círculo negro con una línea que lo atraviesa. Eso no tiene ningún sentido en absoluto. Para este problema particular que han comenzado otra pregunta aquí:Visual Studio 2010 WPF Project ran in debug or relase will not allow drag and drop to any control

Todo esto es debido a la ejecución de Visual Studio como administrador. Aparentemente lo mismo es cierto para notepad.exe, si ejecuta algo como administrador no puede arrastrar y soltar. Así que ahora para la depuración de IIS tengo que ejecutar como administrador y para arrastrar y soltar, necesito descubrir cómo ejecutar en modo normal ...

+0

¿cómo se imagina que nunca conseguir este trabajo? ¿tienes un problema dentro de TreeView1_Drop? si es así, explique lo que necesita y muestre lo que intentó, comience a verificar las propiedades del objeto DragEventArgs e y vea en el momento de la depuración qué contiene y cómo puede usarlo para obtener lo que necesita. lo mismo para esos otros eventos que dejaste vacío ... –

+0

He puesto en negrita la parte de la pregunta que dice que el problema es que los eventos no se activan. Gracias. – 249076

+0

¿Está configurando la variable aceptar elemento del drop y arrastre a true? –

Respuesta

1

Creo que el problema es que no está arrastrando el elemento sobre los TreeViewItems. Esto es necesario porque sus eventos están registrados solo para TreeViewItems. Si desea arrastrar y colocar en un nivel primario de su árbol, deberá agregar los eventos correspondientes a su árbol.

El problema que tendrá con esta solución es que los eventos TreeView se dispararán primero. Entonces ahora vas a tener que saber qué nodo estás para agregarlo correctamente. Hay soluciones para descubrir en qué nodo estás. Sin embargo, le sugiero agregar un elemento de nivel superior a su árbol que siempre está ahí. Luego conecte los eventos a TreeViewItems como lo hace usted. De esta manera, puede agregar en un nivel superior sin tener que manejar los eventos TreeView porque puede arrastrar a ese elemento de nivel superior.

A continuación se muestra lo que solía probar y estoy viendo los puntos de interrupción si arrastro directamente sobre TreeViewItems. Puede que no reconozca algunos espacios de nombres, pero eso se debe a que hace referencia a mi proyecto.

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> 

Código atrás:

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) 
    { 

    } 
+0

He editado la pregunta para enfocarme solo en hacer que los eventos se disparen en la vista de árbol. Recolocé los eventos en treeview y me deshice de los setters de eventos en treeviewitems. Tiene que haber algo extremadamente simple que me falta. Cuando arrastro el archivo sobre la vista de árbol, todo lo que obtengo es un círculo negro con una línea que lo atraviesa. Parece que la liberación del archivo no provoca el lanzamiento del evento. Si pudiera hacer que ese evento se disparara, podría hacer una prueba de impacto, o algo para descubrir en qué nodo se había terminado. – 249076

+0

Lo tengo trabajando en mezcla de expresiones, pero cuando uso el último xaml en el estudio visual no me deja arrastrar y soltar en el panel de la pila dentro de la vista de árbol. Tenía muchas esperanzas porque si conseguía que el panel de la pila arrastrara y soltara, eso pondría en marcha este proyecto. – 249076

+0

Marqué la tuya como la respuesta porque me hizo pensar que algo andaba mal en mi computadora. Eso me llevó a descubrir que no se puede arrastrar y soltar si se está ejecutando como administrador. – 249076

Cuestiones relacionadas