Visão geral de arrastar e soltar

Este tópico fornece uma visão geral do suporte a arrastar e soltar em aplicativos Windows Presentation Foundation (WPF). Arrastar e soltar geralmente se refere a um método de transferência de dados que envolve o uso de um mouse (ou algum outro dispositivo apontador) para selecionar um ou mais objetos, arrastar esses objetos sobre algum destino de soltar desejado na interface do usuário (UI) e soltá-los.

Suporte ao recurso do tipo "arrastar e soltar" no WPF

Normalmente, as operações do tipo "arrastar e soltar" envolvem duas partes: uma origem do arrasto da qual o objeto arrastado se origina e um destino de soltar que recebe o objeto solto. A origem do arrasto e o destino de soltar podem ser elementos de interface do usuário no mesmo ou em outro aplicativo.

O tipo e o número de objetos que podem ser manipulados com o recurso do tipo "arrastar e soltar" é completamente arbitrário. Por exemplo, arquivos, pastas e seleções de conteúdo são alguns dos objetos mais comuns manipulados por meio de operações do tipo "arrastar e soltar".

As ações específicas realizadas durante uma operação do tipo "arrastar e soltar" são específicas ao aplicativo e, frequentemente, determinadas pelo contexto. Por exemplo, arrastar uma seleção de arquivos de uma pasta para outra no mesmo dispositivo de armazenamento move os arquivos por padrão, enquanto arrastar arquivos de um compartilhamento UNC (Convenção Universal de Nomenclatura) para uma pasta local copia os arquivos por padrão.

Os recursos de arrastar e soltar fornecidos pelo WPF são projetados para serem altamente flexíveis e personalizáveis para suportar uma ampla variedade de cenários de arrastar e soltar. As operações do tipo "arrastar e soltar" dão suporte à manipulação de objetos em um único aplicativo ou entre diferentes aplicativos. Arrastar e soltar entre aplicativos WPF e outros aplicativos do Windows também é totalmente suportado.

No WPF, qualquer UIElement ou ContentElement pode participar do arrastar e soltar. Os eventos e métodos necessários para operações de arrastar e soltar são definidos na DragDrop classe. As UIElement classes e ContentElement contêm aliases para os eventos anexados para que os DragDrop eventos apareçam na lista de membros da classe quando um ou ContentElement é herdado como um UIElement elemento base. Os manipuladores de eventos anexados a esses eventos são anexados ao evento anexado subjacente DragDrop e recebem a mesma instância de dados de evento. Para saber mais, confira o evento UIElement.Drop.

Importante

Operações do tipo "arrastar e soltar" OLE não funcionarão se você estiver na zona da Internet.

Transferência de dados

Arrastar e soltar faz parte da área de transferência de dados mais geral. A transferência de dados inclui operações do tipo "arrastar e soltar" e copiar e colar. Uma operação do tipo "arrastar e soltar" é análoga a uma operação de copiar e colar ou de recortar e colar, que é usada para transferir dados de um objeto ou aplicativo para outro usando a área de transferência do sistema. Os dois tipos de operações exigem:

  • Um objeto de origem que fornece os dados.

  • Uma maneira de armazenar temporariamente os dados transferidos.

  • Um objeto de destino que recebe os dados.

Em uma operação de copiar e colar, a área de transferência do sistema é usada para armazenar temporariamente os dados transferidos; Em uma operação de arrastar e soltar, A DataObject é usado para armazenar os dados. Conceitualmente, um objeto de dados consiste em um ou mais pares de um que contém os dados reais e um Object identificador de formato de dados correspondente.

A origem de arrastar inicia uma operação de arrastar e soltar chamando o método estático DragDrop.DoDragDrop e passando os dados transferidos para ele. O DoDragDrop método encapsulará automaticamente os dados em um se DataObject necessário. Para obter maior controle sobre o formato de dados, você pode encapsular os dados em um DataObject antes de passá-los para o DoDragDrop método. O destino de descarte é responsável por extrair os dados do DataObject. Para obter mais informações sobre como trabalhar com objetos de dados, consulte Dados e objetos de dados.

A origem e o destino de uma operação do tipo "arrastar e soltar" são elementos de interface do usuário; no entanto, os dados que realmente são transferidos, normalmente, não têm uma representação visual. É possível escrever um código para fornecer uma representação visual dos dados que são arrastados, assim como ocorre ao arrastar arquivos no Windows Explorer. Por padrão, comentários são fornecidos ao usuário com a alteração do cursor para representar o efeito que a operação do tipo "arrastar e soltar" terá sobre os dados, por exemplo, se os dados serão movidos ou copiados.

Efeitos das operações do tipo "arrastar e soltar"

Operações do tipo "arrastar e soltar" podem ter efeitos diferentes nos dados transferidos. Por exemplo, é possível copiar os dados ou movê-los. WPF define uma enumeração que você pode usar para especificar o efeito de uma DragDropEffects operação de arrastar e soltar. Na origem de arraste, você pode especificar os efeitos que a fonte permitirá no DoDragDrop método. No destino de soltar, você pode especificar o efeito que o destino pretende na Effects propriedade da DragEventArgs classe. Quando o destino de soltar especifica seu efeito pretendido no DragOver evento, essas informações são passadas de volta para a origem de arrastar no GiveFeedback evento. A origem do arrasto usa essas informações para informar ao usuário o efeito que o destino de soltar pretende ter sobre os dados. Quando os dados são descartados, o destino de descarte especifica seu efeito real no Drop evento. Essas informações são passadas de volta para a origem de arraste como o valor de retorno do DoDragDrop método. Se o destino de soltar retornar um efeito que não está na lista allowedEffects da origem do arrasto, a operação do tipo "arrastar e soltar" será cancelada sem nenhuma transferência de dados.

É importante lembrar que, no WPF, os DragDropEffects valores são usados apenas para fornecer comunicação entre a origem de arrastar e o destino de soltar em relação aos efeitos da operação de arrastar e soltar. O efeito real da operação do tipo "arrastar e soltar" depende da escrita do código apropriado no aplicativo.

Por exemplo, o destino de soltar pode especificar que o efeito de soltar dados nele é mover os dados. No entanto, para mover os dados, ele deve ser adicionado ao elemento de destino e removido do elemento de origem. O elemento de origem pode indicar que ele permite a movimentação dos dados, mas se você não fornecer o código para remover os dados do elemento de origem, o resultado final será que os dados serão copiados e não movidos.

Eventos das operações do tipo "arrastar e soltar"

As operações do tipo "arrastar e soltar" dão suporte a um modelo controlado por evento. A origem do arrasto e o destino de soltar usam um conjunto padrão de eventos para manipular operações do tipo "arrastar e soltar". As tabelas a seguir resumem os eventos padrão das operações do tipo "arrastar e soltar". Estes são eventos anexados na DragDrop classe. Para obter mais informações sobre eventos anexados, consulte Visão geral dos eventos anexados.

Eventos de origem do arrasto

Evento Resumo
GiveFeedback Esse evento ocorre continuamente durante uma operação do tipo "arrastar e soltar" e permite que a origem de soltar forneça informações de comentários ao usuário. Geralmente, esses comentários são fornecidos com a alteração da aparência do ponteiro do mouse para indicar os efeitos permitidos pelo destino de soltar. Esse é um evento de propagação.
QueryContinueDrag Esse evento ocorre quando há uma alteração nos estados do teclado ou do botão do mouse durante uma do tipo "arrastar e soltar" e permite que a origem de soltar cancele a operação do tipo "arrastar e soltar", dependendo dos estados da tecla e do botão. Esse é um evento de propagação.
PreviewGiveFeedback Versão de tunelamento do GiveFeedback.
PreviewQueryContinueDrag Versão de tunelamento do QueryContinueDrag.

Eventos de destino de soltar

Evento Resumo
DragEnter Esse evento ocorre quando um objeto é arrastado para os limites do destino de soltar. Esse é um evento de propagação.
DragLeave Esse evento ocorre quando um objeto é arrastado para fora dos limites do destino de soltar. Esse é um evento de propagação.
DragOver Esse evento ocorre continuamente enquanto um objeto é arrastado (movido) dentro do limite do destino de soltar. Esse é um evento de propagação.
Drop Esse evento ocorre quando um objeto é solto no destino de soltar. Esse é um evento de propagação.
PreviewDragEnter Versão de tunelamento do DragEnter.
PreviewDragLeave Versão de tunelamento do DragLeave.
PreviewDragOver Versão de tunelamento do DragOver.
PreviewDrop Versão de tunelamento do Drop.

Para manipular eventos das operações do tipo "arrastar e soltar" em instâncias de um objeto, adicione manipuladores para os eventos listados nas tabelas anteriores. Para manipular eventos de arrastar e soltar no nível da classe, substitua os métodos virtuais On*Event e On*PreviewEvent correspondentes. Para obter mais informações, consulte Manipulação de classes de eventos roteados por classes base de controle.

Implementando operações do tipo "arrastar e soltar"

Um elemento de interface do usuário pode ser uma origem do arrasto, um destino de soltar ou ambos. Para implementar uma operação básica do tipo "arrastar e soltar", um código é escrito para iniciar a operação do tipo "arrastar e soltar" e processar os dados soltos. É possível melhorar essa experiência de "arrastar e soltar" manipulando eventos opcionais das operações do tipo "arrastar e soltar".

Para implementar uma operação básica do tipo "arrastar e soltar", você realizará as seguintes tarefas:

  • Identificar o elemento que será uma origem do arrasto. Uma fonte de arrastar pode ser um ou um UIElementContentElementarquivo .

  • Criar um manipulador de eventos na origem do arrasto que iniciará a operação do tipo "arrastar e soltar". O evento é tipicamente o MouseMove evento.

  • No manipulador de eventos drag source, chame o DoDragDrop método para iniciar a operação de arrastar e soltar. DoDragDrop Na chamada, especifique a origem de arraste, os dados a serem transferidos e os efeitos permitidos.

  • Identificar o elemento que será um destino de soltar. Um destino de queda pode ser UIElement ou um ContentElementarquivo .

  • No destino de soltar, defina a AllowDrop propriedade como true.

  • No destino de descarte, crie um Drop manipulador de eventos para processar os dados descartados.

  • Drop No manipulador de eventos, extraia os dados do usando os GetDataPresentDragEventArgs métodos e GetData .

  • Drop No manipulador de eventos, use os dados para executar a operação de arrastar e soltar desejada.

Você pode aprimorar sua implementação de arrastar e soltar criando um evento de origem e destino de DataObject arrastar e soltar opcional, conforme mostrado nas seguintes tarefas:

  • Para transferir dados personalizados ou vários itens de dados, crie um DataObject para passar para o DoDragDrop método.

  • Para executar ações adicionais durante um arraste, manipule o DragEnter, DragOvere DragLeave eventos no destino de soltar.

  • Para alterar a aparência do ponteiro do mouse, manipule o GiveFeedback evento na origem de arrastar.

  • Para alterar como a operação de arrastar e soltar é cancelada, manipule o QueryContinueDrag evento na origem de arrastar.

Exemplo de operação do tipo "arrastar e soltar"

Esta seção descreve como implementar o recurso de arrastar e soltar para um Ellipse elemento. O Ellipse é uma origem de arrastar e um destino de soltar. Os dados transferidos são a representação de cadeia de caracteres da propriedade da Fill elipse. O XAML a seguir mostra o Ellipse elemento e os eventos relacionados ao arrastar e soltar que ele manipula. Para obter etapas completas de como implementar uma operação do tipo "arrastar e soltar", consulte Passo a passo: Habilitando operações de arrastar e soltar em um controle de usuário.

<Ellipse Height="50" Width="50" Fill="Green"
     MouseMove="ellipse_MouseMove"
     GiveFeedback="ellipse_GiveFeedback"
     AllowDrop="True"
     DragEnter="ellipse_DragEnter" DragLeave="ellipse_DragLeave"
     DragOver="ellipse_DragOver" Drop="ellipse_Drop" />

Habilitando um elemento a ser uma origem do arrasto

Um objeto que é uma origem do arrasto é responsável por:

  • Identificar quando ocorre uma operação de arrastar.

  • Iniciar a operação do tipo "arrastar e soltar".

  • Identificar os dados a serem transferidos.

  • Especificar os efeitos que a operação do tipo "arrastar e soltar" tem permissão para ter sobre os dados transferidos.

A origem do arrasto também pode fornecer comentários ao usuário sobre as ações permitidas (mover, copiar, nenhuma) e pode cancelar a operação do tipo "arrastar e soltar" de acordo com a entrada adicional do usuário, como pressionar a tecla ESC durante a operação de arrastar.

É responsabilidade do aplicativo determinar quando ocorre um arrasto e, em seguida, iniciar a operação de arrastar e soltar chamando o DoDragDrop método. Normalmente, isso ocorre quando um evento ocorre sobre o elemento a ser arrastado enquanto um MouseMove botão do mouse é pressionado. O exemplo a seguir mostra como iniciar uma operação de arrastar e soltar do MouseMove manipulador de eventos de um Ellipse elemento para torná-lo uma fonte de arraste. Os dados transferidos são a representação de cadeia de caracteres da propriedade da Fill elipse.

private void ellipse_MouseMove(object sender, MouseEventArgs e)
{
    Ellipse ellipse = sender as Ellipse;
    if (ellipse != null && e.LeftButton == MouseButtonState.Pressed)
    {
        DragDrop.DoDragDrop( ellipse,
                             ellipse.Fill.ToString(),
                             DragDropEffects.Copy);
    }
}
Private Sub Ellipse_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs)
    Dim ellipse = TryCast(sender, Ellipse)
    If ellipse IsNot Nothing AndAlso e.LeftButton = MouseButtonState.Pressed Then
        DragDrop.DoDragDrop(ellipse, ellipse.Fill.ToString(), DragDropEffects.Copy)
    End If
End Sub

Dentro do manipulador de MouseMove eventos, chame o DoDragDrop método para iniciar a operação de arrastar e soltar. O DoDragDrop método usa três parâmetros:

  • dragSource – Uma referência ao objeto de dependência que é a fonte dos dados transferidos; esta é tipicamente a origem do MouseMove evento.

  • data - Um objeto que contém os dados transferidos, encapsulados em um DataObjectarquivo .

  • allowedEffects - Um dos DragDropEffects valores de enumeração que especifica os efeitos permitidos da operação de arrastar e soltar.

Qualquer objeto serializável pode ser passado no parâmetro data. Se os dados ainda não estiverem encapsulados em um , eles serão automaticamente encapsulados em um DataObjectnovo DataObjectarquivo . Para passar vários itens de dados, você deve criar o si mesmo e passá-lo para o DataObjectDoDragDrop método. Para obter mais informações, consulte Dados e objetos de dados.

O parâmetro allowedEffects é usado para especificar o que a origem do arrasto permitirá que o destino de soltar faça com os dados transferidos. Os valores comuns para uma origem de arraste são Copy, Movee All.

Observação

O destino de soltar também pode especificar quais efeitos ele pretender ter em resposta aos dados soltos. Por exemplo, se o destino de descarte não reconhecer o tipo de dados a ser descartado, ele poderá recusar os dados definindo seus efeitos permitidos como None. Ele normalmente faz isso em seu DragOver manipulador de eventos.

Uma fonte de arrastar pode, opcionalmente, manipular os GiveFeedback eventos e QueryContinueDrag . Esses eventos têm manipuladores padrão que são usados, a menos que você marque os eventos como manipulados. Normalmente, você ignorará esses eventos, a menos que tenha uma necessidade específica de alterar seu comportamento padrão.

O GiveFeedback evento é gerado continuamente enquanto a fonte de arraste está sendo arrastada. O manipulador padrão para esse evento verifica se a origem do arrasto está sobre um destino de soltar válido. Se estiver, ela verificará os efeitos permitidos do destino de soltar. Em seguida, ela fornece comentários ao usuário final sobre os efeitos de soltar permitidos. Geralmente, isso é feito com a alteração do cursor do mouse para um cursor do tipo não soltar, copiar ou mover. Você só deverá manipular esse evento se precisar usar cursores personalizados para fornecer comentários ao usuário. Se você manipular esse evento, lembre-se de marcá-lo como manipulado para que o manipulador padrão não substitua o manipulador.

O QueryContinueDrag evento é gerado continuamente enquanto a fonte de arraste está sendo arrastada. Você pode manipular esse evento para determinar qual ação encerra a operação do tipo "arrastar e soltar", de acordo com o estado das teclas ESC, SHIFT, CTRL e ALT, bem como o estado dos botões do mouse. O manipulador padrão desse evento cancela a operação do tipo "arrastar e soltar" se a tecla ESC é pressionada e solta os dados se o botão do mouse é liberado.

Cuidado

Esses eventos são acionados continuamente durante a operação do tipo "arrastar e soltar". Portanto, você deve evitar tarefas com uso intensivo de recursos nos manipuladores de eventos. Por exemplo, use um cursor armazenado em cache em vez de criar um novo cursor sempre que o GiveFeedback evento for gerado.

Habilitando um elemento a ser um destino de soltar

Um objeto que é um destino de soltar é responsável por:

  • Especificar se ele é um destino de soltar válido.

  • Responder à origem do arrasto quando ele é arrastado para o destino.

  • Verificar se os dados transferidos estão em um formato que pode ser recebido.

  • Processar os dados soltos.

Para especificar que um elemento é um destino de descarte, defina sua AllowDrop propriedade como true. Em seguida, os eventos de destino de soltar serão acionados no elemento, para que você possa manipulá-los. Durante uma operação do tipo "arrastar e soltar", ocorre a seguinte sequência de eventos no destino de soltar:

  1. DragEnter

  2. DragOver

  3. DragLeave ou Drop

O DragEnter evento ocorre quando os dados são arrastados para o limite do destino de soltar. Normalmente, esse evento é manipulado para fornecer uma visualização dos efeitos da operação do tipo "arrastar e soltar", se apropriado para o aplicativo. Não defina a DragEventArgs.Effects propriedade no evento, pois ela será substituída DragOver no DragEnter evento.

O exemplo a seguir mostra o DragEnter manipulador de eventos de um Ellipse elemento. Esse código visualiza os efeitos da operação de arrastar e soltar salvando o pincel atual Fill . Em seguida, ele usa o método para verificar se o GetDataPresent que está sendo arrastado DataObject sobre a elipse contém dados de cadeia de caracteres que podem ser convertidos em um Brusharquivo . Em caso afirmativo, os dados são extraídos usando o GetData método. Em seguida, é convertido em a Brush e aplicado à elipse. A alteração é revertida no manipulador de DragLeave eventos. Se os dados não puderem ser convertidos em um Brush, nenhuma ação será executada.

private Brush _previousFill = null;
private void ellipse_DragEnter(object sender, DragEventArgs e)
{
    Ellipse ellipse = sender as Ellipse;
    if (ellipse != null)
    {
        // Save the current Fill brush so that you can revert back to this value in DragLeave.
        _previousFill = ellipse.Fill;

        // If the DataObject contains string data, extract it.
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            string dataString = (string)e.Data.GetData(DataFormats.StringFormat);

            // If the string can be converted into a Brush, convert it.
            BrushConverter converter = new BrushConverter();
            if (converter.IsValid(dataString))
            {
                Brush newFill = (Brush)converter.ConvertFromString(dataString);
                ellipse.Fill = newFill;
            }
        }
    }
}
Private _previousFill As Brush = Nothing
Private Sub Ellipse_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
    Dim ellipse = TryCast(sender, Ellipse)
    If ellipse IsNot Nothing Then
        ' Save the current Fill brush so that you can revert back to this value in DragLeave.
        _previousFill = ellipse.Fill

        ' If the DataObject contains string data, extract it.
        If e.Data.GetDataPresent(DataFormats.StringFormat) Then
            Dim dataString = e.Data.GetData(DataFormats.StringFormat)

            ' If the string can be converted into a Brush, convert it.
            Dim converter As New BrushConverter()
            If converter.IsValid(dataString) Then
                Dim newFill As Brush = CType(converter.ConvertFromString(dataString), Brush)
                ellipse.Fill = newFill
            End If
        End If
    End If
End Sub

O DragOver evento ocorre continuamente enquanto os dados são arrastados sobre o destino de soltar. Esse evento é emparelhado com o GiveFeedback evento na origem de arrastar. DragOver No manipulador de eventos, você normalmente usa os métodos e GetData para verificar se os GetDataPresent dados transferidos estão em um formato que o destino de recebimento pode processar. Também é possível verificar se teclas modificadoras são pressionadas, o que geralmente indica se o usuário pretende executar uma ação de mover ou copiar. Depois que essas verificações forem executadas, você definirá a propriedade para notificar a DragEventArgs.Effects fonte de arrastar sobre o efeito que soltar os dados terá. A fonte de arrastar recebe essas informações no GiveFeedback evento args e pode definir um cursor apropriado para dar feedback ao usuário.

O exemplo a seguir mostra o DragOver manipulador de eventos de um Ellipse elemento. Esse código verifica se o que está sendo arrastado DataObject sobre a elipse contém dados de cadeia de caracteres que podem ser convertidos em um Brusharquivo . Em caso afirmativo, ele define a DragEventArgs.Effects propriedade como Copy. Isso indica à origem do arrasto que os dados podem ser copiados para a elipse. Se os dados não puderem ser convertidos em um Brush, a DragEventArgs.Effects propriedade será definida como None. Isso indica à origem do arrasto que a elipse não é um destino de soltar válido para os dados.

private void ellipse_DragOver(object sender, DragEventArgs e)
{
    e.Effects = DragDropEffects.None;

    // If the DataObject contains string data, extract it.
    if (e.Data.GetDataPresent(DataFormats.StringFormat))
    {
        string dataString = (string)e.Data.GetData(DataFormats.StringFormat);

        // If the string can be converted into a Brush, allow copying.
        BrushConverter converter = new BrushConverter();
        if (converter.IsValid(dataString))
        {
            e.Effects = DragDropEffects.Copy | DragDropEffects.Move;
        }
    }
}
Private Sub Ellipse_DragOver(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
    e.Effects = DragDropEffects.None

    ' If the DataObject contains string data, extract it.
    If e.Data.GetDataPresent(DataFormats.StringFormat) Then
        Dim dataString = e.Data.GetData(DataFormats.StringFormat)

        ' If the string can be converted into a Brush, convert it.
        Dim converter As New BrushConverter()
        If converter.IsValid(dataString) Then
            e.Effects = DragDropEffects.Copy Or DragDropEffects.Move
        End If
    End If
End Sub

O DragLeave evento ocorre quando os dados são arrastados para fora do limite do destino sem serem descartados. Você manipula esse evento para desfazer qualquer coisa que você fez no manipulador de DragEnter eventos.

O exemplo a seguir mostra o DragLeave manipulador de eventos de um Ellipse elemento. Esse código desfaz a visualização executada DragEnter no manipulador de eventos aplicando o salvo Brush à elipse.

private void ellipse_DragLeave(object sender, DragEventArgs e)
{
    Ellipse ellipse = sender as Ellipse;
    if (ellipse != null)
    {
        ellipse.Fill = _previousFill;
    }
}
Private Sub Ellipse_DragLeave(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
    Dim ellipse = TryCast(sender, Ellipse)
    If ellipse IsNot Nothing Then
        ellipse.Fill = _previousFill
    End If
End Sub

O Drop evento ocorre quando os dados são descartados sobre o destino de soltar, por padrão, isso acontece quando o botão do mouse é liberado. Drop No manipulador de eventos, você usa o GetData método para extrair os dados transferidos do DataObject e executar qualquer processamento de dados que seu aplicativo exige. O Drop evento encerra a operação de arrastar e soltar.

O exemplo a seguir mostra o Drop manipulador de eventos de um Ellipse elemento. Esse código aplica os efeitos da operação de arrastar e soltar e é semelhante ao código no DragEnter manipulador de eventos. Ele verifica se o ser arrastado DataObject sobre a elipse contém dados de cadeia de caracteres que podem ser convertidos em um Brusharquivo . Em caso afirmativo, o Brush é aplicado à elipse. Se os dados não puderem ser convertidos em um Brush, nenhuma ação será executada.

private void ellipse_Drop(object sender, DragEventArgs e)
{
    Ellipse ellipse = sender as Ellipse;
    if (ellipse != null)
    {
        // If the DataObject contains string data, extract it.
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            string dataString = (string)e.Data.GetData(DataFormats.StringFormat);

            // If the string can be converted into a Brush,
            // convert it and apply it to the ellipse.
            BrushConverter converter = new BrushConverter();
            if (converter.IsValid(dataString))
            {
                Brush newFill = (Brush)converter.ConvertFromString(dataString);
                ellipse.Fill = newFill;
            }
        }
    }
}
Private Sub Ellipse_Drop(ByVal sender As System.Object, ByVal e As System.Windows.DragEventArgs)
    Dim ellipse = TryCast(sender, Ellipse)
    If ellipse IsNot Nothing Then

        ' If the DataObject contains string data, extract it.
        If e.Data.GetDataPresent(DataFormats.StringFormat) Then
            Dim dataString = e.Data.GetData(DataFormats.StringFormat)

            ' If the string can be converted into a Brush, convert it.
            Dim converter As New BrushConverter()
            If converter.IsValid(dataString) Then
                Dim newFill As Brush = CType(converter.ConvertFromString(dataString), Brush)
                ellipse.Fill = newFill
            End If
        End If
    End If
End Sub

Confira também