Em WPF, uma Shape (retângulos, elipses, linhas,..) é um FrameworkElement e recebe os eventos de mouse e teclado, como qualquer outro FrameworkElement (botões, por exemplo). Isto é muito diferente de WinForms, onde as formas desenhadas usando GDI+ são apenas desenhos na tela e não recebem nenhum evento.
Podemos usar isso para movimentar nossas shapes com o mouse usando os eventos PreviewMouseLeftButtonDown, PreviewMouseLeftButtonUp e PreviewMouseMove.
Inicialmente, colocamos algumas shapes no Canvas:
Como podemos ver, colocamos os manipuladores de eventos no Canvas. Devido ao recurso de Bubbling e Tunneling, os eventos são propagados por toda a árvore de elementos e, quando clicamos em qualquer uma das shapes, o Canvas recebe o evento também. Assim, podemos processar os eventos em um único local, não nos preocupando de atribuir os manipuladores para cada shape do desenho.
No código fonte, definimos alguns campos auxiliares:
O manipulador para o evento PreviewMouseLeftButtonDown é:
Aqui, inicializamos a variável start com a posição que o mouse foi clicado, configuramos isDragging para true, deixamos o elemento semi-transparente e capturamos o mouse. O manipulador para o evento PreviewMouseMove é:
Aqui verificamos se estamos arrastando um elemento. Se estivermos, pegamos a nova posição do mouse, recalculamos a posição da Shape e movemos. Como a posição é dada por attached properties, devemos usar SetValuee GetValue para obter e alterar as propriedades Canvas.Left e Canvas.Top. Finalmente, fechamos o movimento no evento PreviewMouseLeftButtonUp:
Aqui apenas restauramos os valores. Uma coisa que deve ser notada é que estamos alterando a propriedade Canvas.ZIndex. Isto é devido ao fato que queremos que os elementos que movemos fiquem sempre por cima dos outros. Assim, usamos a variável currentZ para guardar o ZIndex, incrementando-o a cada movimento, de maneira que a cada vez que movemos um elemento, ele tenha um ZIndex maior que o anterior.
Desta maneira, podemos mover os elementos dentro de uma janela WPF. Note que este código pode ser estendido a qualquer FrameworkElement, não sendo apenas para Shapes.
O projeto completo está em https://github.com/bsonnino/ShapesMove
Hi … can we have access to the demo source project ??
thanks in advance
Sure. You can get it on http://www.revolution.com.br/dragshapes.zip