Arraste e solte arquivos no WPF

106

Eu preciso colocar um arquivo de imagem em meu aplicativo WPF. Atualmente, tenho um evento disparando quando coloco os arquivos, mas não sei o que fazer a seguir. Como faço para obter a imagem? O senderobjeto é a imagem ou o controle?

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?
}
Eamonn McEvoy
fonte

Respostas:

211

Isso é basicamente o que você deseja fazer.

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

Além disso, não se esqueça de realmente conectar o evento em XAML, bem como definir o AllowDropatributo.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>
AR
fonte
incrível funciona muito bem, basta trocar "HandleFileOpen (arquivos [0]);" para "foreach (arquivo de string em arquivos) {Openfile (arquivo);}" - Obrigado :)
Eamonn McEvoy
1
Desculpe :) Quer dizer, arrastar e soltar não funciona. AllowDropé definido como True, mas o Dropmanipulador de eventos nunca é chamado. Quando arrasto um arquivo sobre a janela, vejo um símbolo circular "negado"
mcont
4
Usei um Gridcomo elemento raiz, com um Borderinterior com a Backgroundpropriedade definida como algo (branco é bom, mas não transparente). Dentro do Bordercoloquei o conteúdo real.
março
1
Definir o fundo como transparente funcionou bem para mim ao tentar soltar em uma grade. Aparentemente, você precisa de um plano de fundo para que o teste de clique aconteça. Graças a esta entrada do blog: codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf
DustinA
1
Uma pegadinha real é que se você executar o VisualStudio como Admin - depure seu aplicativo - e arraste do FileExplorer como não administrador, o contexto de segurança é diferente e nenhum evento de arrastar será acionado. Custou-me 30 minutos de vida.
Hans Karlsen
35

O arquivo de imagem está contido no eparâmetro, que é uma instância da DragEventArgsclasse .
(O senderparâmetro contém uma referência ao objeto que gerou o evento.)

Especificamente, verifique o e.Datamembro ; conforme a documentação explica, isso retorna uma referência ao objeto de dados ( IDataObject) que contém os dados do evento de arrastar.

A IDataObjectinterface fornece vários métodos para recuperar o objeto de dados que você procura. Você provavelmente vai querer começar chamando o GetFormatsmétodo para descobrir o formato dos dados com os quais está trabalhando. (Por exemplo, é uma imagem real ou simplesmente o caminho para um arquivo de imagem?)

Então, depois de identificar o formato do arquivo que está sendo arrastado, você chamará uma das sobrecargas específicas do GetDatamétodo para realmente recuperar o objeto de dados em um formato específico.

Cody Gray
fonte
12

Além da resposta de AR, observe que se você quiser usar o TextBoxdrop, você deve saber as seguintes coisas.

TextBoxparece já ter algum tratamento padrão para DragAndDrop. Se o seu objeto de dados for um String, ele simplesmente funcionará. Outros tipos não são manipulados e você obtém o efeito de mouse Proibido e seu manipulador Drop nunca é chamado.

Parece que você pode ativar seu próprio tratamento com e.Handledpara true em um PreviewDragOvermanipulador 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);  
     }
}
Desenvolvedor
fonte
1
O exemplo de AR não usa o manipulador PreviewDragOver, que é importante para fazer tudo funcionar. Kudos.
Greg Vogel