WPF Drag & Drop in Grid Sample

Drag and Drop, ce n'est peut être pas si facile. Bien souvent il manque quelques astuces de bases comme par exemple quand on Drop dans une Grid on aimerait bien savoir dans quelle cellule on a dropé l'objet.

Alors on part de l'exemple MSDN :
Drag and Drop on a user control

MSDN Drag and Drop Sample
On écrit une couleur dans le TextBox et en la dropant  dans un des cercles on change la couleur du cercle, on peut copier un cercle en le dropant en maintenant la touche contrôle appuyée.

C'est intéressant mais il nous manque tout un tas de choses. Ce que j'aimerais faire c'est dropper des objets dans une Grid savoir où il sont dans la Grid et pouvoir commencer réellement à jouer avec mes objets.

Il est par exemple intéressant de jouer avec les propriétés de ma Grid et d'y déplacer les objets :

Grid.SetRow(object,x), Grid.SetColumn, Grid.SetColumnSpan,Grid.SetRowSpan
Je sais maintenant déplacer mes objets dans la Grid mais où sont -ils ?

Grid.GetRow(object,x),  object.GetValue(Grid.RowProperty)
 Et voilà que je peux commencer à jouer.

Mais je voudrais aller plus loin et pouvoir dropper mes objects mais qu'ils ne se chevauchent pas. Pouvoir leur donner la taille que je veux en la changeant dans un menu contextuel et toujours en évitant qu'ils ne se chevauchent.

Voilà l'exemple que je vous propose :

WPF Drag&Drop Sample CanDrop and CanResize
Vous trouverez dans le code source suivant, la création dynamique d'objets dans la grille pour détecter où les objets sont droppés. Et tout un tas d'autres astuces vous permettant de réellement bien commencer avec le Drap&Drop en WPF.

Requirements :
WPF .NET 4.0
Visual Studio 2010
Microsoft.Practices.Prism
Microsoft.Practices.Prism.Interactivity
Microsoft.Practices.Prism.UnityExtension
Microsoft.Practices.Prims.Unity
Download and Setup Prism Library 5.0 for WPF
Inutile de préciser que les packages nugets sont difficiles à installer en ce qui concerne Prism et ses différentes version, en constante modification de version de namespace... bref la résolution de vos problèmes passera peut être par l'exécution de la commande : PM> Install-Package CommonServiceLocator dans la "Console du gestionnaire de package" suivie de PM> Install-Package Prism.UnityExtensions -Version 4.1.0

Download Sample

Si vous souhaitez aller plus loin et notamment en fonctionnant avec le modèle MVVM, je vous recommande vivement les articles suivants :
Drag and Drop in WPF
Drag and Drop in WPF - Part II

Je que j'apprécie vraiment dans ce Sample c'est la mise en place d'un "Adorner", une parure qui à travers  une Property DragAdornerTemplate liée à une DependencyProperty affiche une image en transparence lorsque l'on déplace les objets. Dans le Xaml de la façon suivante :

<ListBox dd:DragDrop.DragAdornerTemplate="{StaticResource PupilDragAdorner}">

Prism InteractionRequest Popup a Window (2)

Dans un post précédent : Prism InteractionRequest Popup a Window (1)on a vu l'utilisation de prism:InteractionRequestTrigger pour déclencher une InteractionRequest permettant de récupérer le ViewModel d'une fenêtre secondaire et à l'intérieur de ce ViewModel une propriété publique SelectedItem. Ainsi dans la fenêtre principale on peut afficher le choix effectué par l'utilisateur dans la fenêtre secondaire :

Récupération du choix utilisateur effectué dans le module Prism HelloWorldModule

Prism Popup a Window comment ça marche ?

La fenêtre Clients implémente l'interface IPopupWindowActionAware de la Class Library Infrastructure cette interface possède deux propriétés :

namespace Infrastructure.InteractionRequests
{
    public interface IPopupWindowActionAware
    {
          Window HostWindow { get; set; }
          Notification HostNotification { get; set; }
    }
}

Et là on est au coeur de cet exemple, l'objet PopupWindowAction dérive de TriggerAction<FrameworkElement>, il utilise des DependencyProperty pour modifier l'apparence de la Popup et override la fonction void Invoke(object parameter) pour construire la Popup et faire à la fin :

// IsModal 
// public static readonly DependencyProperty IsModalProperty
if (this.IsModal)
{
wrapperWindow.ShowDialog();
}
else
{
wrapperWindow.Show();
}

Ainsi le fenêtre secondaire est ou non Modale. Oui je passe rapidement et vous laisse le soin de lire ces sources et d'évaluer leur complexité.

Prism Popup a Window conclusion

Déjà l'on voit qu'une réflexion intense doit être menée à la naissance d'un projet WPF Prism afin de décrire le comportement des différents modules et de leurs interactions. Cette réflexion (ou conception) donne naissance au projet de Class Library Infrastructure qui s'occupe du comportement MVVM des objets utilisés et interagissants dans les différents modules.

Mais ce n'est pas nouveau, il vaut mieux toujours, passer un peu de temps en conception afin d'être certain que l'architecture choisie répondre aux besoins que de se jeter à pisser du code.