Arrastra y suelta archivos en WPF


106

Necesito colocar un archivo de imagen en mi aplicación WPF. Actualmente tengo un evento que se activa cuando dejo caer los archivos, pero no sé qué hacer a continuación. ¿Cómo obtengo la imagen? ¿El senderobjeto es la imagen o el control?

private void ImagePanel_Drop(object sender, DragEventArgs e)
{
    //what next, dont know how to get the image object, can I get the file path here?
}

Respuestas:


211

Esto es básicamente lo que quieres hacer.

private void ImagePanel_Drop(object sender, DragEventArgs e)
{

  if (e.Data.GetDataPresent(DataFormats.FileDrop))
  {
    // Note that you can have more than one file.
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

    // Assuming you have one file that you care about, pass it off to whatever
    // handling code you have defined.
    HandleFileOpen(files[0]);
  }
}

Además, no olvide conectar el evento en XAML, así como configurar el AllowDropatributo.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>

impresionante funciona de maravilla, simplemente intercambiado "HandleFileOpen (files [0]);" a "foreach (archivo de cadena en archivos) {Openfile (archivo);}" - Gracias :)
Eamonn McEvoy

1
Lo siento :) Quiero decir que arrastrar y soltar no funciona. AllowDropse establece en True, pero Dropnunca se llama al controlador de eventos. Cuando arrastro un archivo sobre la ventana, veo un símbolo circular "denegado"
mcont

4
Usé Gridcomo elemento raíz, con un Borderinterior con la Backgroundpropiedad establecida en algo (el blanco está bien, pero no transparente). Dentro del Borderpongo el contenido real.
mcont

1
Establecer el fondo en transparente funcionó bien para mí cuando intenté colocarlo en una cuadrícula. Aparentemente, necesitas un fondo para que se realice la prueba. Gracias a esta entrada de blog: codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf
DustinA

1
Un problema real es que si ejecuta VisualStudio como administrador, depura su aplicación, y arrastra desde FileExplorer como no administrador, el contexto de seguridad es diferente y no se activarán eventos de arrastre. Me costó 30 minutos de vida.
Hans Karlsen

35

El archivo de imagen está contenido en el eparámetro, que es una instancia de la DragEventArgsclase .
(El senderparámetro contiene una referencia al objeto que generó el evento).

Específicamente, verifique al e.Datamiembro ; como explica la documentación, esto devuelve una referencia al objeto de datos ( IDataObject) que contiene los datos del evento de arrastre.

La IDataObjectinterfaz proporciona una serie de métodos para recuperar el objeto de datos que busca. Probablemente desee comenzar llamando al GetFormatsmétodo para averiguar el formato de los datos con los que está trabajando. (Por ejemplo, ¿es una imagen real o simplemente la ruta a un archivo de imagen?)

Luego, una vez que haya identificado el formato del archivo que se está arrastrando, llamará a una de las sobrecargas específicas del GetDatamétodo para recuperar el objeto de datos en un formato particular.


12

Además de la respuesta de AR, tenga en cuenta que si desea usar TextBoxpara soltar, debe saber lo siguiente.

TextBoxparece tener ya un manejo predeterminado para DragAndDrop. Si su objeto de datos es un String, simplemente funciona. Otros tipos no se manejan y obtienes el efecto de mouse Prohibido y nunca se llama a tu manejador Drop.

Parece que puede habilitar su propio manejo e.Handleden verdadero en un PreviewDragOvercontrolador de eventos.

XAML

<TextBox AllowDrop="True"    x:Name="RtbInputFile"      HorizontalAlignment="Stretch"   HorizontalScrollBarVisibility="Visible"  VerticalScrollBarVisibility="Visible" />

C#

RtbInputFile.Drop += RtbInputFile_Drop;            
RtbInputFile.PreviewDragOver += RtbInputFile_PreviewDragOver;

private void RtbInputFile_PreviewDragOver(object sender, DragEventArgs e)
{
    e.Handled = true;
}

private void RtbInputFile_Drop(object sender, DragEventArgs e)
{
     if (e.Data.GetDataPresent(DataFormats.FileDrop))
     {
                // Note that you can have more than one file.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                var file = files[0];                
                HandleFile(file);  
     }
}

1
El ejemplo de AR pierde el controlador PreviewDragOver, que es un poco importante para que todo funcione. Prestigio.
Greg Vogel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.