Astuce Silverlight : ajouter une gestion de l’événement de la molette de la souris à vos contrôles - #S009

image

Dans l’astuce #23 (en Anglais), Mike Snow nous montre comment capturer l’événement de la molette de la souris. Dans cette astuce, nous allons le reprendre en implémentant l’interface IMouseWheelObserver de vos éléments et contrôles Silverlight qui peuvent en hériter. De cette façon, à n’importe quel moment où l’on utilisera la molette de la souris sur votre contrôle, il en sera notifié.

Le code suivant est la déclaration de l’interface pour IMouseWheelObserver :

 
 
public interface IMouseWheelObserver
{
    void OnMouseWheel(MouseWheelArgs args);
    event MouseEventHandler MouseEnter;
    event MouseEventHandler MouseLeave;
}

 

 L’événement OnMouseWheel() passe l’objet EventArgs quand l’événement est déclenché pour votre contrôle. Ces arguments :
  1. Traquer les combinaisons de clé Maj., Ctrl et Alt.
  2. Traquer la différence de scrolling faite par la molette de la souris.
 public class MouseWheelArgs : EventArgs
 {
     private readonly double
         _Delta;
  
     private readonly bool
         _ShiftKey,
         _CtrlKey,
         _AltKey;
  
  
     public double Delta
     {
         get { return this._Delta; }
     }
  
     public bool ShiftKey
     {
         get { return this._ShiftKey; }
     }
  
     public bool CtrlKey
     {
         get { return this._CtrlKey; }
     }
  
     public bool AltKey
     {
         get { return this._AltKey; }
     }
  
     public MouseWheelArgs(double delta, bool shiftKey, bool ctrlKey, bool altKey)
     {
         this._Delta = delta;
         this._ShiftKey = shiftKey;
         this._CtrlKey = ctrlKey;
         this._AltKey = altKey;
     }
 }

Ensuite, regardons du côté de l’implémentation de la classe WheelMouseListener. Dans cette classe nous devons :

  1. Appeler les méthodes HTMLPage pour attacher la création des événements de scrolling de la souris.
  2. Appeler les méthodes HTMLPage pour détacher les événements de scrolling de la souris quand la classe est détruite.
  3. Déclarer une pile d’éléments. Nous gardons au dessus de la pile, les éléments sur laquelle la souris est. De cette façon, nous connaissons les élements que nous devons appeler lorsque l’événement de scrolling de la souris a été déclenché.

 

 public class WheelMouseListener
 {
     private Stack<IMouseWheelObserver> _ElementStack;
  
     private WheelMouseListener()
     {
         this._ElementStack = new Stack<IMouseWheelObserver>();
  
         HtmlPage.Window.AttachEvent("DOMMouseScroll", OnMouseWheel);
         HtmlPage.Window.AttachEvent("onmousewheel", OnMouseWheel);
         HtmlPage.Document.AttachEvent("onmousewheel", OnMouseWheel);
  
         Application.Current.Exit += new EventHandler(OnApplicationExit);
     }
  
     /// <summary>
     /// Detaches from the browser-generated scroll events.
     /// </summary>
     private void Dispose()
     {
         HtmlPage.Window.DetachEvent("DOMMouseScroll", OnMouseWheel);
         HtmlPage.Window.DetachEvent("onmousewheel", OnMouseWheel);
         HtmlPage.Document.DetachEvent("onmousewheel", OnMouseWheel);
     }
  
     public void AddObserver(IMouseWheelObserver element)
     {
         element.MouseEnter += new MouseEventHandler(OnElementMouseEnter);
         element.MouseLeave += new MouseEventHandler(OnElementMouseLeave);
     }
  
     private void OnMouseWheel(object sender, HtmlEventArgs args)
     {
         double delta = 0;
         ScriptObject e = args.EventObject;
  
         if (e.GetProperty("detail") != null)
         {
             // Mozilla and Safari
             delta = ((double)e.GetProperty("detail"));
         }
         else if (e.GetProperty("wheelDelta") != null)
         {
             // IE and Opera
             delta = ((double)e.GetProperty("wheelDelta"));
         }
  
         delta = Math.Sign(delta);
  
         if (this._ElementStack.Count > 0)
             this._ElementStack.Peek().OnMouseWheel(new MouseWheelArgs(delta, args.ShiftKey, args.CtrlKey, args.AltKey));
     }
  
     private void OnElementMouseLeave(object sender, MouseEventArgs e)
     {
         this._ElementStack.Pop();
     }
  
     private void OnElementMouseEnter(object sender, MouseEventArgs e)
     {
         this._ElementStack.Push((IMouseWheelObserver)sender);
     }
  
     private void OnApplicationExit(object sender, EventArgs e)
     {
         this.Dispose();
     }
  
     private static WheelMouseListener _Instance = null;
  
     public static WheelMouseListener Instance
     {
         get
         {
             if (_Instance == null)
             {
                 _Instance = new WheelMouseListener();
             }
  
             return _Instance;
         }
     }
 }
 Voici trois modifications que vous avez besoin de faire à vos contrôles :
  1. Hériter de l’interface IMouseWheelObserver
  2. Inscrire l’écouteur d’événement en appelant WheelMouseListener.Instance.AddObserver(this); depuis vos constructeurs de classe des contrôles.
  3. Ajouter la méthode OnMouseWheel() à vos contrôles qui devront être appelés quand l’événement est déclenché.

Exemple :

 public partial class Toolbar : UserControl, IMouseWheelObserver
 {
     public Toolbar()
     {
         InitializeComponent();
  
         WheelMouseListener.Instance.AddObserver(this);
     }
  
     public void OnMouseWheel(MouseWheelArgs args)
     {
         // Process the event here...
     }
 }

Enfin, je voudrai remercier Laith Alasad (Laith.Alasad@hyro.com) pour cette idée et pour la contribution de code ci-dessus.s

Syndication : Mike Snow’s Weblog
Traduction autorisée par Mike Snow.