Laden...

Eigene Steuerelemente entwerfen?

Erstellt von PoWl vor 15 Jahren Letzter Beitrag vor 15 Jahren 10.148 Views
P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren
Eigene Steuerelemente entwerfen?

Hi,

kann man eigene Steuerelemente auch mit der Express Edition von Visual C# 2008 erstellen oder braucht man dazu Visual Studio?

kennt jemand ein Tutorial dafür? Ich meine hier im Forum mal was gesehen zu haben aber ich finde es einfach nicht mehr.

lg PoWl

1.346 Beiträge seit 2008
vor 15 Jahren

Das geht mit jedem VS. Erstelle einfach eine neue Klasse und leite sie von Control ab. Dann überschreibst du die OnPaint Methode, und zeichnest darin deine Sachen.

Gruß pdelvo

1.130 Beiträge seit 2007
vor 15 Jahren

Das geht mit jedem VS.

Das ist so etwas irreführend, denn es geht auch ohne jedes VS, man braucht nur einen Compiler und das .net Framework.

Wenn man den designer des Visual Studios nutzen will und andere fertige Controls damit auf dem eigenen erstellen will, geht das am besten, indem man dem Projekt ein neues Element hinzufügt und im dialog als typ Usercontrol(Benutzersteuerelement) wählt.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

1.346 Beiträge seit 2008
vor 15 Jahren

Er hat ja nur nach VS gefragt. Also ist meine Antwort richtig. er sagte auch das er "eigene" und nicht ein aus mehreren Control zusammengesetztes haben möchte.

Gruß pdelvo

1.130 Beiträge seit 2007
vor 15 Jahren

OnPaint überschreiben kann er dann ja immernoch zusätzlich...

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

1.346 Beiträge seit 2008
vor 15 Jahren

UserControl ist aber nicht dafür gedacht.(Er könnte Theoretich eine Texhtbox nehmen, es ergibt aber keinen Sinn)

Gruß pdelvo

1.130 Beiträge seit 2007
vor 15 Jahren

UserControl ist aber nicht dafür gedacht.

bei allem fast allem, was von control erbt, kann man das aussehen ändern und das ist auch so gedacht, sonst würde es diese möglichkeit sicherlich nicht geben und man müsste sich mit den Windowsnachrichtn herumschlagen. bei einem Usercontrol hat man lediglich die Möglichkeit, zusätzlich den designer zu benutzen, um fertige controls oder komponenten einzubauen.

(Er könnte Theoretich eine Texhtbox nehmen,

Womit wir bei den wenigen Controls wären, wo das nicht geht. Außerdem:

es ergibt aber keinen Sinn)

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

1.346 Beiträge seit 2008
vor 15 Jahren

Geht das wirklich nicht? Ich würde einfach das base.OnPaint rausnehmen.

Gruß pdelvo

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo PoWl,

siehe Tutorial Komponentenerstellung gesucht

herbivore

1.130 Beiträge seit 2007
vor 15 Jahren

Geht das wirklich nicht? Ich würde einfach das base.OnPaint rausnehmen.

Der Text einer Textbox wird automatisch vom Betriebssystem und außerhalb von WM_PAINT (also auch außerhalb von OnPaint) gezeichnet, sobald man etwas auswählt oder den Text bearbeitet. Umgehen kann man das nur, indem man die Nonclientarea (den Ramenbereich) auf die gesamte Textbox ausdehnt und dann in ncpaint zeichnet. Mit dem .net Framework allein kommt man also nicht weit.

Ich würde einfach das base.OnPaint rausnehmen

das würde so oder so nix bringen, da die Textbox nicht im base.Onpaint gezeichte wird, sondern die Paint-Meldung anstatt OnPaint überhaupt aufzurufen gleich an die originale Textbox-Fenterprozedur (oder wie man das auf deutsch nennen mag 🤔 ) weitergereicht wird.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

Ja also ich habe mir vor Kurzem eine Klasse RoundTrackbar geschrieben die ein Label, das man auf 100x100 skaliert hat in eine runde Trackbar verwandelt, wie im Bild zu sehen ist. Nun wollte ich das noch eine nummer geschickter machen so, dass das Label selbst die RoundTrackbar ist und ich sie im Designer von VS direkt aus der Steuerelemente-Liste in mein Form reinziehen kann. Geht das dann auch mit Icon und so, dass man im Designer schon sieht wie das hinterher ungefär aussehen könnte? Kann man wie bei anderen Steuerelementen auch eigene Einträge in die Eigenschaftenliste reinsetzen um hinterher das aussehen schon im Designer einzustellen?

Ich erstelle also ein leeres Projekt und füge dann ein "Benutzersteuerelement" hinzu. Anstelle von UserControl leite ich es von Label ab, da label ja praktischerweise schon den zentrieren "xx%"-Text enthält und ich den Kreis einfach nur noch drum rumzeichnen muss.

Oder würde ihr es lieber bei meiner Methode, die bereits vorhandenen Label durch eine Instanz der Klasse RoundTrackbar verwalten zu lassen? Ich muss dann halt zu jedem Label eine Instanz erstellen und kann nicht direkt die Label-Instanz verwenden. Ist im Prinzip aber egal solange es funktioniert, ich wage mich jedoch gerne mal an neues heran und versuche das Optimum zu erreichen^^

lg PoWl

1.346 Beiträge seit 2008
vor 15 Jahren

Natürlich geht das. Du musst der Eigenschaft das Attribute Browsable geben. Hier ein Beispiel:


[Browsable(true)]
public int Value
{
...
}

Gruß pdelvo

O
778 Beiträge seit 2007
vor 15 Jahren

Hallo pdelvo, Hallo PoWl,

Du musst der Eigenschaft das Attribute Browsable geben

genau falsch, weil true ist der Standardwert für Browsable. Du musst also das Attribut setzen, wenn du die Eigenschaft nicht im Designer angezeigt bekommen willst. Gleichfalls wäre es bei den Eigenschaften noch nett, wenn du ein DescriptionAttribute und ein CategoryAttribute mit angibst, dann steht die Eigenschaft nachher nicht unter Sonstige und ohne Hilfetext da.

Zu dem Problem mit dem von Label oder UserControl ableiten: Ich würde dir dringend davon abraten von Label abzuleiten, weil das fertige Control ist für meine Begriffe kein Label. Es ist eher ein Steuerelement, was eine Fließkommazahl visualisiert. Dann sollte man aber auch nicht die Möglichkeit haben über eine Text-Eigenschaft auf den Text des Labels direkt zugreifen zu können. Ich würde dir schon sehr empfehlen, das ganze zu kapseln, sprich von Control oder der Einfachheit wegen von UserControl ableiten.

Gruß

Georg

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

OK, das ist im Prinzip ja kein Problem, dann leite ich es von UserControl ab. Wie kann ich erreichen, dass das Steuerelement dann hinterher im Designer auch so angezeigt wird wie es hinterher auch im fertigen Programm erscheint, wie die anderen Steuerelemente auch? Die Grafischen Elemente müssen ja erst im laufenden Programm berechnet werden. Oder kann man das irgendwie vorkompilieren so dass er schon im Designer ein fertig gezeichnetes Steuerelement einsetzt?

Tut mir leid wenn ich mich noch etwas unbeholfen tue aber ich habe mich vor ein paar Monaten auf C# gestürzt und seither nichts mehr gemacht. Die RoundTrackbar-Geschichte ist das Projekt, womit ich nun wieder gerade frisch angefangen hab. Daher muss ich mich erstmal tiefer ins Gebiet reinarbeiten.

lg PoWl

5.299 Beiträge seit 2008
vor 15 Jahren

Ack.
In meinen Augen zeigt das Bild ein UserControl mit einer HScrollbar (DockStyle.Bottom) und einem selbst-gezeichnetem Visualisierungs-Bereich (ein Control mit DockStyle.Fill).

Für den VisualisierungsBereich würde ich ein neues Control schaffen, von Control abgeleitet, mit OnPaint().
Erst aufs Usercontrol ziehen, und dann mit [ToolboxItem(False)] attributieren, weil man wills ja nicht ständig inne Toolbox herumfahren haben, oder? 😉

Die Designer-Unterstützung ergibt sich von selbst. Man muß aber bes. sauber proggen, weil Fehler im Designer schlecht zu debuggen sind.

Der frühe Apfel fängt den Wurm.

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

Also die HScrollBar gehört nicht dazu, sry falls das verwirrt hat. Genau, es geht darum eine Grad-Zahl (0-360°) zu visualisieren. Danke für die Hilfe bisher, ich werde das nachher einfach mal probieren und mich dann zurückmelden wenn ich nicht weiterkomme.

Im Anhang mal das Programm damit ihr euch das vorstellen könnt. die Trackbar kann man natürlich mit der Maus auch anfassen. Die Trackbar ist noch nicht mit der HScrollBar verbunden, jedoch die HScrollBar mit der Trackbar 😉

5.299 Beiträge seit 2008
vor 15 Jahren

Äh - du denkst doch nicht, dass ich auf eine downgeloadete .exe klickse?

Der frühe Apfel fängt den Wurm.

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

Grr, ich kanns ja nachvollziehen aber es ist einfach nur traurig und nervig, dass man in nem Programmiererforum gleich als potenzieller böser Cracker hingestellt wird, der eine konkrete Problemstellung im Forum + eine .exe-Datei postet, einzig und allein um anderen damit Schaden zuzufügen indem die .exe dann sein System vernichtet.

Im Anhang nochmal das ganze VS Projekt ohne irgendwelche Exen.
Diejenigen die es interessiert, dürfen es gerne runterladen, kompilieren, und sich anschauen. Die anderen dürfen es gerne einfach ignorieren.

lg PoWl

1.346 Beiträge seit 2008
vor 15 Jahren

Nicht jeder öffnet einfach so exe Dateien, von Leuten, die er nicht kennt.

Gruß pdelvo

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

Klar kennt ihr mich nicht, aber habt ihr schon Leute getroffen die so krank sind erstmal so einen Thread ans laufen zu kriegen um dann ne exe zu posten, nur um damit fremde Systeme zu zerstöreren oder generell anderen zu schaden? Passiert das so oft? Das kommt mir grad so vor wie als dürfte ich morgens beim Bäcker keine Brötchen mehr holen weil sie vergiftet sein könnten.

5.299 Beiträge seit 2008
vor 15 Jahren

Ja, mag schon sein, mein Reflex etwas überkandidelt.
Ist halt Reflex - aber glaub, im Grunde ganz nützlich 😉 .

Aber ich hab mal das OwnerDrawing von dein Teil in einem Control implementiert.
Das mittm MausMove müssteste also noch selbst dranmachen.
Schwieriger wirds, wennde auch noch haben willst, dasses als Rechteck noch gut aussieht. Dann musste nämlich anfangen, mittm Matrix-Objekt den GraphicsPath zu transofmieren, und müsstest den Original-Path vorhalten, um auf geänderte Formen des Controls eingehen zu können.
Lohnt sich evtl. nicht, die Arbeit zu machen.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;

namespace RoundTrackbarV2 {
   public class RoundTrackbar : Control {

      private int _angle = 270;
      private int _innerSize;
      private StringFormat _sf = new StringFormat() {
         Alignment = StringAlignment.Center,
         LineAlignment = StringAlignment.Center
      };
      private readonly GraphicsPath _pth = new GraphicsPath();

      [DefaultValue(270)]
      public int Angle {
         get { return _angle; }
         set {
            _angle = value;
            this.Invalidate();
         }
      }
      protected override void Dispose(bool disposing) {
         if (disposing) {
            _sf.Dispose();
            _pth.Dispose();
         }
         base.Dispose(disposing);
      }
      protected override void OnHandleCreated(EventArgs e) {
         base.OnHandleCreated(e);
         GetInnerSize();
      }
      private void GetInnerSize() {
         using (var g = this.CreateGraphics()) {
            _innerSize = Convert.ToInt32(g.MeasureString("288%", base.Font).Width * 1.42f) + 2;
         }
      }
      protected override void OnFontChanged(EventArgs e) {
         base.OnFontChanged(e);
         GetInnerSize();
      }
      protected override void OnPaint(PaintEventArgs e) {
         base.OnPaint(e);
         Graphics g = e.Graphics;
         g.DrawString(_angle.ToString() + "%", base.Font, Brushes.Black, base.ClientRectangle, _sf);
         g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
         var rct = new Rectangle((this.Width - _innerSize) / 2, (this.Height - _innerSize) / 2, _innerSize, _innerSize);
         _pth.Reset();
         _pth.AddArc(rct, 0, Angle);
         rct = this.ClientRectangle;
         rct.Size -= new Size(1, 1);
         _pth.AddArc(rct, Angle, -Angle);
         _pth.CloseFigure();
         g.FillPath(Brushes.Orange, _pth);
         g.DrawPath(Pens.Black, _pth);
      }
   }
}

Der frühe Apfel fängt den Wurm.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo PoWl,

Grr, ich kanns ja nachvollziehen aber es ist einfach nur traurig und nervig, dass man in nem Programmiererforum gleich als potenzieller böser Cracker hingestellt wird,

das hat keiner getan. Dein Control ist ja noch in der Entwicklung. Es könnte einfach aufgrund eines Programmierfehlers unabsichtlich Schaden anrichten. Wie wahrscheinlich das ist, kann man der EXE nicht ansehen und so ohne weiteres also nicht einschätzen. Insofern solltest du keinem böse sein, der einfach nur vorsichtig ist.

herbivore

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

@herbi, daran habe ich nicht gedacht, bin natürlich auch keinem böse der vorsichtig ist! Ich kanns ja nachvollziehen, wie ich schon sagte, trotzdem ist es traurig und nervig das kann man nicht ganz leugnen 😉. Kann denn so ein einfaches control tatsächlich Schaden anrichten?

@ ErfinderDesRades, danke für deine Arbeit! Ich habe gerade versucht das zu verwertern aber ich weiß nicht wie. Alle Tuorials im Internet gehen von Visual Studio aus, ich hab allerdings nur die Express-Version. Und da kann man, wenn man ein neues Projekt erstellt kein Steuerelement als Vorlage nehmen. Ich hab versucht ein leeres Projekt zu erstellen, dann ein Benutzersteuerelement hinzuzufügen und als Sourcecode deinen Code verwendet. Allerdings weiß ich nicht wie ich dann weitermachen soll, wie daraus dann am Ende tatsächlich ein Steuerlement wird.

Sagtmal, liegen Steuerelemente normalerweise dann nicht als .dll vor?

lg PoWl

5.299 Beiträge seit 2008
vor 15 Jahren

Kann denn so ein einfaches control tatsächlich Schaden anrichten?

Eine gestartete Exe kann ungefähr alles, was der aktuelle Benutzer des Computers auch kann. Wenn ich also als Admin eine Exe starte, kann die glaub sogar einen Dienst installieren, der fürderhin immer angeht, wenn der Compi startet, oder so Scherze.

@ ErfinderDesRades, danke für deine Arbeit! Ich habe gerade versucht das zu verwertern aber ich weiß nicht wie. 1.Mach an dein Projekt eine Datei "RoundTrackbar2.cs". 1.Kopier den Code rein. 1.Drück F6. 1.Zieh aus der Toolbox ein "RoundTrackbar" aufs Form.

Fettschrift, Schriftgröße und so kannste im Designer über die Font-Property einstellen.

Alle Tuorials im Internet gehen von Visual Studio aus, ich hab allerdings nur die Express-Version. Und da kann man, wenn man ein neues Projekt erstellt kein Steuerelement als Vorlage nehmen. Ich hab versucht ein leeres Projekt zu erstellen, dann ein Benutzersteuerelement hinzuzufügen und als Sourcecode deinen Code verwendet.

Wassich gebastelt hab geht ohne UserControl, das erbt direkt von Control


   public class RoundTrackbar : Control {  /* ... */  }

Sagtmal, liegen Steuerelemente normalerweise dann nicht als .dll vor?

ist häufig sinnvoll, aber nicht zwingen nötig.

Der frühe Apfel fängt den Wurm.

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

Ah, na das funktioniert ja prima, danke! Ich werde auf dieser Basis mal weitermachen 😃

Ja klar, eine exe kann viel böses, es ging mir eher um herbivores Beschreibung, dass man ja nicht unbedingt was böses vom User erwarten müsse sondern einfach nur eine Fehlfunktion des Programms. Und da fragte ich nun was an einem Control so fehlfunktionieren könnte, dass es in der Lage ist, dem System ernsthafte Schäden zuzufügen.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo PoWl,

das Control könnte ja Debug-Code enthalten. Es könnte z.B. log-Dateien erstellen und diese beim Start immer löschen, damit nur die Einträge vom aktuellen bzw. letzten Lauf enthalten sind. Das Löschen könnte der Einfachheit halber so implementiertem sein, dass alle Dateien aus einem bestimmten Verzeichnis (z.B. dem Arbeitsverzeichnis) gelöscht werden ...

herbivore

P
PoWl Themenstarter:in
219 Beiträge seit 2008
vor 15 Jahren

OK, überredet 😉

Noch ein paar Fragen:
Wie kann ich dem Steuerelement ein OnValueChanged-Event hinzufügen?
//Edit: Gelöst.

Wie könnte ich außerdem noch Auswahlfelder in den Designer einfügen mit dem ich z.B. die Farbe auswählen kann?
// Edit: hat sich erledigt, im 🛈 stehts

Wie kann ich ein vorhandenes Rectangle am besten um 1 Pixel nach rechts und nach unten verschieben und um 2px in beide Richtungen kleiner machen?
// Edit: hat sich erledigt, darf aber trotzdem beantwortet werden

Noch offen:

Wie könnte ich erreichen, dass das das Steuerelement immer genauso Breit, wie auch hoch gemacht werden kann?

Was hat das [DefaultValue:(xxx)] für einen Effekt? Ob ich das drin stehen hab oder nicht ändert nichts an allem. Im Designer erscheinen auch nur die Anfangswerte, mit denen ich die Variablen initialisiere.

Ich habe das Steuerelement nun als .dll vorliegen und jedes mal wenn ich es in einem Programm verwende wird diese .dll im Release-Verzeichnis dazukopiert. Kann ich das ganze auch komplett in einer .exe verpacken oder muss ich den Steuerelement-Code irgendwie in mein aktuelles Projekt mit aufnehmen oder gar dafür umschreiben?

lg PoWl