http://michael.carbenay.info

Créer un conteneur WPF « draggable » (part 2)

23 nov. 2007  –  .net 3.0 | WPF  –  0 Commentaires

Où l'on commence l'implémentation du contrôle

Pour commencer l'implémentation de ce contrôle, nous allons nous concentrer sur la détection du « gesture » : c'est assez simple, il suffit que l'utilisateur clique sur le contrôle et bouge d'au moins quelques pixels en maintenant le bouton gauche de la souris pour démarrer le drag/drop.

Commençons par créer notre classe :

using System;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows;

namespace Carbenay.Michael.Controls
{
    public class DraggableBorder : Border
    {
    }
}

Il faut ensuite détecter le mouvement de déclenchement :

  • Lorsque l'on clique sur l'élément (événement MouseDown) nous allons conserver la position de la souris
  • Lorsque l'on bouge la souris sur l'élément (évenement MouseMove) après ce clic, il faudra comparer la position de la souris actuelle par rapport a celle au moment de l'appui et si celle-ci est suffisamment différents – ce « suffisamment » étant défini par un paramètre de Windows – déclencher le drag/drop
  • Lorsque le bouton de la souris est relâché au dessus de l'élément (événement MouseUp), le drag/drop est annulé

Pour être sûr de traiter les événements le plus tôt possible, nous n'allons pas vraiment nous connecter aux événements MouseDown, MouseMove, MouseUp mais à leur version « Preview » (pour plus de renseignement sur les événements et leur versions Preview, je vous conseille Application = Code + Markup de Charles Petzold) :

 

    public DraggableBorder()
    {
        PreviewMouseDown += new MouseButtonEventHandler(MyPreviewMouseDown);
        PreviewMouseMove += new MouseEventHandler(MyPreviewMouseMove);
        PreviewMouseUp += new MouseButtonEventHandler(MyPreviewMouseUp);
    }
    
    // position de la souris sur le MouseDown
    private Point _mouseDownPoint = new Point();
    // a true si le MouseDown a bien été détecté 
    // dans le controle
    private bool _wasMouseDownInControl = false;

    void MyPreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        // on "annule" le drag drop
        _wasMouseDownInControl = false;
    }


    void MyPreviewMouseMove(object sender, MouseEventArgs e)
    {
        // si le bouton gauche de la souris est toujours 
        // appuyé on regarde si la position actuelle
        // est suffisament eloignée de la position de
        // départ et si oui, on lance le drag/drop
        if (e.LeftButton == MouseButtonState.Pressed 
            && _wasMouseDownInControl)
        {
            Point pos = e.GetPosition(null);

            if (SystemParameters.MinimumHorizontalDragDistance <=
Math.Abs(position.X - _mouseDownPoint.X) || SystemParameters.MinimumVerticalDragDistance <=
Math.Abs(position.Y - _mouseDownPoint.Y)) { BeginDrag(); _wasMouseDownInControl = false; e.Handled = true; return; } } } void MyPreviewMouseDown(object sender, MouseButtonEventArgs e) { // on enregistre la position de la souris // pour détecter le mouvement de drag/drop _mouseDownPoint = e.GetPosition(null); _wasMouseDownInControl = true; }

Reste la méthode BeginDrag dont le rôle est de préparer les données et de déclencher le drag/drop. Pour cette première version nous allons faire très simple et créer un objet de donnée avec une ligne de texte simple :

    private void BeginDrag()
    {
        DataObject data = new DataObject();
        data.SetData(DataFormats.Text, "Test");
        DragDropEffects de = DragDrop.DoDragDrop(this, 
                                data, 
                                DragDropEffects.Copy);
    }
Au programme du prochain numéro : qu'est-ce que le DataObject et qu'est-il possible d'y mettre ?

Ajouter un commentaire


(Affichera votre icône Gravatar)

biuquote
  • Commentaire
  • Aperçu immédiat
Loading