Klicks auf Objekte zur Design-Zeit

Der im Visual Studio enthaltene Designer für Windows Forms ist ein grosser Fortschritt gegenüber früheren Programmen, z.B. dem Designer in Visual Basic 6. Und doch: Wenn es darum geht, Forms zu entwerfen, die eine Menge Controls haben, würde man sich viele Dinge einfacher wünschen, mit weniger Eingaben, und mit weniger Mausklicks.

Als ich kürzlich eben eine solche komplexe Form entwerfen musste, kam mir das Label-Control als besonders schlechtes Beispiel in dieser Beziehung vor: Jede Menge Eigenschaften, so viele, dass es häufig ein paar Klicks braucht, bis man sich bis zur einzigen Eigenschaft „durchgekämpft“ hat, die man wirklich routinemässig ändern möchte: den Text des Labels.

Mit der Zeit sagte ich mir, wie wunderbar es doch wäre, einfach ein Label im Designer anklicken zu können, um eine Dialogbox hervorzuholen mit einem Eingabefeld für das Ändern des Label-Textes!

Es gibt da nur ein kleines, aber entscheidendes Problem: Wie schafft man es, zur Design-Zeit an diesen Klick heranzukommen, um eigenen Code für die Anzeige besagter Eingabebox anhängen zu können? Es ist ja so, dass das Ereignis OnMouseClick eines Labels normalerweise im Designer nicht feuert, denn damit wäre ja das normale Funktionieren des Designers nicht mehr gewährleistet.

Hierzu ein verwandtes Beispiel, das noch viel klarer mögliche Probleme mit solchen Ereignissen illustriert: Stellen Sie sich vor, Sie haben für ein Control Drag-und-Drop-Logik implementiert, die plötzlich triggert, wenn Sie das Control im Designer verschieben…

Aber es geht trotzdem, und ein bisschen Suchen via Google und Ausprobieren hat folgende Lösung zu Tage gebracht: Man leitet eine eigene Klasse ab von Windows.Forms.Label und stattet diese mit einem sogenannten Designer aus, der nur gerade 1 Methode GetHitTest zu implementieren braucht. Damit kann man erreichen, dass selbst zur Design-Zeit unter bestimmten Umständen, die man frei selbst bestimmen kann, die Methode OnMouseClick des Labels aufgerufen wird.

In diese Methode baut man dann z.B. die Anzeige einer Dialogbox für die Abfrage eines neuen Textes ein, natürlich noch geschützt durch eine Abfrage von DesignMode, damit man nicht umgekehrt zur Laufzeit des Programms Ärger bekommt, wenn jemand den Label anklicken sollte.

Ich habe die Sache experimentell mal so geregelt, dass ein Klick auf die linke Hälfte des Labels wie gehabt an den Designer geht und ein Klick in die rechte Hälfte des Labels selbst zum Ändern des Textes. Das hat sich bisher als recht brauchbar erwiesen.

Im Code sieht das ganze so aus:

  class TritonLabelDesigner : System.Windows.Forms.Design.ControlDesigner {

    protected override bool GetHitTest(Point point) {
      TritonLabel hitLabel = (TritonLabel)Component;
      Point localPoint = hitLabel.PointToClient(point);
      if (localPoint.X > (hitLabel.Width / 2)) {
        return true;
      }
      else {
        return false;
      }
    }
  }

  [DesignerAttribute(typeof(TritonLabelDesigner))]
  public partial class TritonLabel : Label {
    public TritonLabel() {
      InitializeComponent();
    }

    protected override void OnMouseClick(MouseEventArgs e) {
      base.OnMouseClick(e);
      if (DesignMode) {
        // gewünschte DesignTime-Verarbeitung
      }
    }
  }
Veröffentlicht in Keine Kategorie. Schlagwörter: , , , . 1 Comment »

Eine Antwort to “Klicks auf Objekte zur Design-Zeit”

  1. Forcierte Updates für den Forms-Designer « Das Megos .NET-Weblog Says:

    […] nicht mitbekommt. Dies ist speziell dann der Fall, wenn man wie in einem früheren Blog-Eintrag hier beschrieben quasi “hinterrücks” Eigenschaften eines Controls ändert, ohne dass der […]


Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: