Laden...

eigenes Steuerelement

Erstellt von twon vor 20 Jahren Letzter Beitrag vor 20 Jahren 3.934 Views
T
twon Themenstarter:in
3 Beiträge seit 2003
vor 20 Jahren
eigenes Steuerelement

Hi,
ich bin was den Umgang mit C# betrifft noch recht grün hinter den Ohren. Ich würde gerne für ein kleines Programm ein eigenes Steuerelement entwerfen. Ob das jetzt sinnvoll ist oder ob ich auch auf fertige Lösungen zurückgreifen könnte ist mir egal, denn ich würde gerne die Technik verstehen wie ich es durchzuführen habe.
Fakt ist, ich muss mein Steuerelement mit jedem OnPaint-Ereigniss mit den GDI-Funktionen neu zeichnen. Ich weiss wie ich auf diese Funktionen zugreife. Ich weiß auch, wie ich die Ereignisse abfangen kann. Allerdings nur solange ich mich in meiner Hauptklasse befinde. Ein eigenes Steuerelement sollte ja logischerweise in einer seperaten Klasse sein. Diese Klasse muss ich dann in der Hauptklasse intialisieren. Damit aber meine Klasse überhaupt weiss in welchen Eventhandler sie sich einklinken muss, muss ich der Steuerelementklasse dies ja irgendwie mitteilen. Und hier stehe ich auf dem Schlauch. 2 Möglichkeiten fallen mir dazu ein:

  1. Ich übergebe das Formularobjekt bei der Initialisierung der Klasse als Referenzparameter an das Steuerelement.
  2. Ich übergebe dem Steuerelement bei der Initialisierung das Fensterhandle und greife über diesen auf den Eventhandler der Formularklasse zu

zu 1)
folgendes habe ich probiert:
das Steuerelement mit


public Mycontrols.Control1 test;
test = new Mycontrols.Control1(ref MainFrm);

initialisiert.

in der Steuerelementklasse habe ich dann folgendes geschrieben:

public Control1(ref object Sender)
{
object Sender.OnPaint += new System.Windows.Forms.PaintEventHandler(this.OnPaint);	
}

Bei der Versuch überhäufte mich der Compiler mit Fehlern (wäre ja auch zu einfach gewesen um wahr zu sein 😄)

zu 2)
Ich habe keine Ahnung ob man mit C# überhaupt auf die Handle zugreifen kann, und wenn ja wie.

Wenn also irgendjemand nen guten Vorschlag hat, wie man das am besten macht her damit.

mfg twon

P
939 Beiträge seit 2003
vor 20 Jahren

Das Ereignis zum Neuzeichnen kommt nicht vom Formular oder so, sondern vom eigenen Steuerelement. Man kann das Steuerelement also neu zeichnen, indem man sich beim Paint-Ereignis registriert.

public class MyControl : Control {

    public MyControl() {
        Paint += new PaintEventHandler(HandlePaint);
    }

    private void HandlePaint(object sender, PaintEventArgs e) {
        // Control zeichnen.
    }
}

Der gängige Weg ist jedoch, die geschütze OnPaint-Methode im Control zu überschreiben.

protected override void OnPaint(PaintEventArgs e) {
    // Control zeichnen.
}

Gruß
Pulpapex

Edit: Das Fenster-Handle braucht man dabei überhaupt nicht. Mit e.Graphics bekommt man das Graphics-Objekt, das alle Funktionen zum Zeichnen auf der Control-Fläche bereithält.

T
twon Themenstarter:in
3 Beiträge seit 2003
vor 20 Jahren

Ok. Ich hätte mit eigentlich denken können dass es dafür bereits eine vorgefertigte Klasse gibt. Das ganze habe ich jetzt auch mal ausprobiert, mit dem Ergebnis dass es nicht funktioniert hat.
Beide von dir genannten Möglichkeiten habe ich ausprobiert. Ich habe keinen Plan was ich falsch gemacht habe, aber meine Paint-funktion wird nie ausgeführt.

Mal nen Blick in die Hauptklasse:


...
public class Testprogramm : Form;
{
   ...
   public MyControls.TestControl test;
   ...
   public Testprogramm()
   {
      ...
      test = new MyControls.TestControl(0,0,300,300);
      ...
   }
}

Hier hierdazu die passende Klasse:


namespace MyControls
{
   public class TestControl : Control
   {
      public Testcontrol()
      {
      }
      protected override void OnPaint(PaintEventArgs e)
      {
         Graphics g= e.Graphics;
         Pen myPen(Color.FromArgb(255,255,255,255),1);
         g.DrawLine(myPen,0,0,400,400);
      }
   }
}


Nun, wenn man bedenkt dass im Grunde genommen bei Windows alles ein Fenster ist, bedeutet dies dass das Control ein Unterfenster des Hauptforumalers ist. Folglich müssen die in irgendeiner Weise in Beziehung stehen. Und das bringt mich wieder auf den Punkt den ich nicht verstehe. Woher weiss das Steuerelement zu welcher Fensterklasse es gehören soll, wenn es ihm nicht mitgeteilt wurde. Eigentlich ist es logisch zu welchem Fenster es gehören soll, da die Definition ja in der entsprechenden Fensterklasse stattfindet. Aber prüft die Klasse Control dieses und wenn ja wie? Oder muss ich noch selbst Hand anlegen? Habe ich in meinem obig genennaten Code irgendwelche Initialisierungen vergessen?

P
939 Beiträge seit 2003
vor 20 Jahren

Dein TestControl wurde noch nicht zum Form hinzugefügt.

public Testprogramm() { 
    TestControl testControl = new TestControl();
    Controls.Add(testControl);
} 

Lies dir doch mal den Abschnitt "Creating Windows Forms Applications" in der .Net Framework Doku durch. Hier gibt es das online, du hast es aber auch lokal auf der Platte.

T
twon Themenstarter:in
3 Beiträge seit 2003
vor 20 Jahren

OK. Die Doku bin ich durchgegangen und prompt auch auf den Abschnitt "Entwicklung von Windows Forms-Steuerelementen" gestoßen 😁 . Das dortige Beispiel habe ich versucht nachzubauen. Allerdings mit dem gleichen Ergebnis. Die OnPaint-Methode des Steuerelemnts wird nie aufgerufen. An der Hauptklasse kann der Fehler meiner Meinung nach nicht mehr liegen. Ersetzte ich mein Control durch ein anderes z.b. ne Textbox funktioniert dies wunderbar.
Der Compiler meldet keinerlei Fehler (benutzte .NET SDK mit Sharpdevelop). Auch wie in dem Beispiel erklärt habe ich mein Steuerelemnt in eine seperate dll verpackt und dann meinem Projekt hinzugefügt. Hat leider auch nichts gebracht.
Irgendjemand noch eine Idee?

Gelöschter Account
vor 20 Jahren

Wenn sich dein Control im Form befindet und die OnPaint-Methode hat, die du gepostest hast, müsste es eigentlich funktionieren.

... sehe gerade woran es liegen könnte. Kann es sein, dass du mit einem weissen Stift auf weissem Hintergrund zeichnest?? Wenn's das auch nicht ist, müsstest du mal bisschen mehr Code posten.