Laden...

Rubberband

Erstellt von ErfinderDesRades vor 15 Jahren Letzter Beitrag vor 15 Jahren 7.191 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 15 Jahren
Rubberband

Kleines Snippet, wie man mit ControlPaint.DrawReversibleFrame() so Auswahlrechtecke implementieren kann.
Funktioniert gut, aber nur auf unbewegten Untergründen.
Wird der ReversibleFrame dagegen durch andere Zeichenvorgänge übermalt, kommts quasi zu "Fehlbildungen".

using System;
using System.Drawing;
using System.Windows.Forms;

namespace nsRubberband {
   /* Prinzip mit ControlPaint.DrawReversibleFrame(): einmal Zeichnen - machts sichtbar. 
    * Exakt noch mal drüber zeichnen: isses wieder weg
    * Hier wird übrigens kein Event geraist - der Aufrufer muß selbst im _MouseUp die 
    * Rubberband.Rectangle-Property abfragen
    */

   public class Rubberband {

      private Rectangle _Rectangle;
      private Size _anchor;

      public Rectangle Rectangle {
         get {
            Rectangle rct = _Rectangle;
            // DrawReversibleFrame verarbeitet zwar auch Rechtecke mit negativer Breite oder Höhe,
            // aber doch lieber umrechnen, weil GDI kanns z.B. nicht. 
            if (rct.Width < 0) {
               rct.X += rct.Width;
               rct.Width *= -1;
            }
            if (rct.Height < 0) {
               rct.Y += rct.Height;
               rct.Height *= -1;
            } 
            return rct;
         }
      }

      public void Start(object sender, MouseEventArgs e) {
         if (e.Button != MouseButtons.Left) throw new ArgumentException(
            "I only start when MouseButtons.Left is clicked!", "e.Button");
         _Rectangle = new Rectangle(Control.MousePosition, Size.Empty);
         _anchor = new Size(Rectangle.X, Rectangle.Y);
         ControlPaint.DrawReversibleFrame(Rectangle, Color.Yellow, FrameStyle.Thick); //erstmaliges Zeichnen
         Control ctl = (Control)sender;
         ctl.MouseMove += ctl_MouseMove;
         ctl.MouseUp += ctl_MouseUp;
      }

      void ctl_MouseMove(object sender, MouseEventArgs e) {
         ControlPaint.DrawReversibleFrame(Rectangle, Color.Yellow, FrameStyle.Thick); //löschen
         Point pt = Control.MousePosition;
         _Rectangle.Size = new Size(pt - _anchor);
         ControlPaint.DrawReversibleFrame(Rectangle, Color.Yellow, FrameStyle.Thick); //neuzeichnen
      }

      void ctl_MouseUp(object sender, MouseEventArgs e) {
         ControlPaint.DrawReversibleFrame(Rectangle, Color.Yellow, FrameStyle.Thick); //letztmaliges löschen
         Control ctl = (Control)sender;
         ctl.MouseMove -= ctl_MouseMove;
         ctl.MouseUp -= ctl_MouseUp;
      }
   }
}


Nachtrag: Gestartet wird im _MouseDown des Forms, und im MouseUp kann z.B. das Rectangle "abgeholt" werden.

Schlagwörter: Rubberband, Auswahlrechteck, auswahl

Der frühe Apfel fängt den Wurm.