[WPF] Drag And Drop avec Windows Presentation Foundation
J’ai eu l’occasion, il n’y a pas si longtemps, d’aider un petit jeune à préparer (certains diront « à faire »
) ses démonstrations pour l’évènement Codes-SourceS qui a eu lieu Mardi 6 Juin 2006.
Une des fonctionnalités qu’il m’a été demandé était de pouvoir utiliser le Drag And Drop dans une application de démonstration.
Etant donné que cela n’est pas aussi simple que cela pourrait paraitre, j’ai décidé de faire ce post pour vous expliquer la marche à suivre.
Il y a 4 étapes :
-
Activer le Déposer (Drop) sur la cible de votre Glisser/Déposer (Drag&Drop)
-
Copier les données
-
Effectuer le changement d’icône au passage de la souris sur la cible
-
Récupérer les données lors du Déposer sur la cible
1ère étape : Activer le Déposer (Drop) sur la cible de votre Glisser/Déposer (Drag&Drop):
Pour cela, il vous suffit de positionner à Vrai (« True ») la propriété « AllowDrop » du contrôle qui va recevoir les données lors du Glisser/Déposer (Drag&Drop) :
<l:ListBox3D AllowDrop="True" />
2ème étape: Copier les données:
La deuxième étape est relativement simple : il vous suffit tout simplement de copier les données depuis votre contrôle source, afin de pouvoir les utiliser ultérieurement.
Pour cela, voici le code que vous devez utiliser dans l’évènement MouseMove de votre contrôle source :
private void MouseMoveMethode(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DragDropEffects effects;
DataObject obj = new DataObject();
obj.SetData(typeof(string), Source_De_Vos_Données);
effects = DragDrop.DoDragDrop(Contrôle_Source, obj, DragDropEffects.Copy | DragDropEffects.Move);
}
}
Je vais tacher de vous commenter rapidement ce code. L’évènement MouseMove sera déclenché à chaque fois que la souris sera déplacée sur le contrôle. Lors de cet évènement, nous exécutons la méthode MouseMoveMethode, qui est chargée de tester si le bouton gauche (le bouton utilisé pour le Glisser/Déposer) est appuyé. Dans ce cas, nous appelons la méthode DoDragDrop qui se charge de copier les données dans le press-papier.
Notez bien que dans cette méthode, il y a des choses que vous aurez besoin de personnaliser :
· Dans la méthode SetData, vous devez spécifier le type des données à copier, ainsi que l’emplacement de ces données
· Dans la méthode DoDragDrop, vous devez indiquer le contrôle qui est la source de ces données. Il vous faudra également indiquer les différents effets possibles qu’il vous sera possible d’utiliser lors du Glisser/Déposer.
3ème étape : Effectuer le changement d’icône au passage de la souris sur la cible:
Maintenant, il vous faudra, sur votre contrôle cible, indiquer qu’elle devra être l’icône à utiliser lorsque vous souris survolera ce contrôle, lors de l’action de Déposer. Pour cela, dans l’évènement DragOver du contrôle cible, utiliser ce code :
private void DragOverMethode(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.None;
}
}
Ce code se charge de vérifier si vous avez bien des données d’un certains type dans le presse-papier. Dans ce cas là, lors du survole du contrôle cible par la souris, l’icône changera d’une certaine façon. Sinon, elle restera la même.
Là encore, cette méthode peut-être personnalisée, et surtout la méthode GetDataPresent, qui prend en paramètre le type de données que vous voulez utiliser. Autrement dit, vous devez mettre le même type que celui que vous avez mis dans la méthode SetData.
4ème étape : Récupérer les données lors du Déposer sur la cible:
La dernière étape est celle où vous allez récupérez les données du presse-papier, pour les manipuler dans votre contrôle cible.
Pour cela, vous devez implémenter l’évènement Drop de votre contrôle source.
private void DropMethode(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effects = DragDropEffects.Copy;
string uri = (string)e.Data.GetData(typeof(string));
// Utiliser uri comme vous le souhaitez
}
else
{
e.Effects = DragDropEffects.None;
}
}
Cette méthode se charge de vérifier si des données sont présente dans le presse-papier. Si c’est bien le cas, alors on récupère ces données en effectuant les conversions, et les tests sur les types, qui vont bien.
Voici un exemple complet :
XAML :
<l:ListBox3D AllowDrop="True" DragOver="CarouselCSDragOver" Drop="CarouselCSDrop" Grid.Row="1" Height="768" Width="1024" x:Name="CarouselCS" Visibility="Visible" Style="{DynamicResource Carousel3DStyleCS}" />
<ListBox Grid.Row="2" Name="m_LstListVideos" Style="{StaticResource ListVideoStyle}" MouseMove="MouseMoveLstListVideos">
<ListBoxItem>
<MediaElement Volume="0" LoadedBehavior="Play" Source="Media\Intro.wmv" />
</ListBoxItem>
</ListBox>
C#:
private void MouseMoveLstListVideos(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DragDropEffects effects;
DataObject obj = new DataObject();
obj.SetData(typeof(string), ((MediaElement)((ListBoxItem)this.m_LstListVideos.SelectedItem).Content).Source.ToString());
effects = DragDrop.DoDragDrop(this.m_LstListVideos, obj, DragDropEffects.Copy | DragDropEffects.Move);
}
}
private void CarouselCSDragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.None;
}
}
private void CarouselCSDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effects = DragDropEffects.Copy;
string uri = (string)e.Data.GetData(typeof(string));
// Utiliser uri comme vous le souhaitez
}
else
{
e.Effects = DragDropEffects.None;
}
}
Et voila, votre application gère dorénavant le Glisser/Déposer (Drag&Drop).
J’espère que cela vous a fait plaisir ![Wink [;)]](/emoticons/emotion-5.gif)
A+
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :