Moin Leutz,
da mir langweilig war wollte ich mich mal einem kleinen Tutorial widmen. Dies erfordert natürlich grundlegende Kenntnisse in VB.NET und Klassenbibliotheken.
Ich wollte mich speziell darauf spezialisieren wie man Controls flüssig laufend erstellen kann. Als Beispiel nehmen wir eine ProgressBar als Control. Zwar gab es dazu schon mal einen Thread, aber dieser hatte Codeteile, die nicht mehr aktuell sind bzw. Nachteile haben.
Vorwort:
Los geht's
So, wir erstellen nun einfach mal eine simple ProgressBar.
Diese wird einen Hintergrund besitzen und einen einfachen Balken. Ihr könnt natürlich mehr Effekte adden, indem Ihr HatchStyles etc benutzt. Steht alles im Tutorial, was ich oben gepostet habe.
Zudem müsst Ihr dann bei manchen Sachen Änderungen vornehmen.
Also wir erstellen uns erstmal ein neues Projekt in Visual Studio (Visual Basic).
Dazu wählen wir Visual Basic als Programmiersprache aus (wenn Ihr VB als IDE habt und nicht VS, dann fällt dieser Schritt weg) und schließlich als Typ:
So nun haben wir eine Klasse in unserem Projekt, die heißt standardmäßig

Dieser befindet sich im Projekt rechts oben.
Dann macht Ihr einen Doppelklick auf die Class1 und könnt nun einen neuen Namen hineinschreiben. Bestätigt Eure Eingabe mit
So, nun haben wir das Ganze umbenannt. Alles was jetzt in unserer Klasse steht ist:
So, um nun ein Control zu erstellen müssen wir vom Control erben. Damit dies funktioniert fehlt uns ein Imports-Anweisung.
Für GDI+ benötigen wir übrigens noch mehr, darum fasse ich gleich alle zusammen. Diese fügt Ihr über
Ich füge dort auch noch die Anweisung für
So, das sieht nun so aus:
Ok, nun können wir loslegen. Wir lassen unsere Klasse nun von
Warum nicht
Ganz einfach. Wenn wir von ProgressBar erben haben wir zwar schon unsere Eigenschaften, wie Value etc., die wir mit
Also erben wir vom
Dazu schreiben wir unter
So, bei manchen kann jetzt ein Fehler kommen. Wenn dies der Fall ist, dann nutzt einfach die Möglichkeit von Visual Studio, klickt doppelt auf den Fehler und wählt den Korrekturvorschlag.
So, nun müssen wir wie für jedes Control, das erbt, einen Konstruktor angeben. Dies geschieht mit
In diesem Konstruktor wird nun unser Control erstellt:
Nun folgen die Einstellungen zur Qualität, damit das Ganze flüssig und ohne flackern läuft.
Dies sind die Einstellungen, die am Besten geeignet sind. Wichtig ist auf jeden Fall hauptsächlich:
Wichtig: Dies kommt auf keinen Fall ins OnPaint, sondern immer in den Konstruktor. Danke @Artentus: für den Tipp.
Ihr könnt noch optional
So.
Das wäre alles wichtige. Nun kommt das Zeichnen der ProgressBar selbst und Sachen wie Properties.
Ich rate euch für eure Properties, Functions etc eigene Regions zu erstellen. Dies geht mit:
Der Übersicht zu Liebe. Okay, um nun Sachen wie
Erklärung:
Die Variablen, die wir hier erstellen dienen dazu einen Standardwert zu geben.
Bei Maximum ist dieser beispielsweise 100. Ihr könnt aber auch 50 nehmen, oder was Euch halt gefällt.
Nehmt für die Variablenamen immer geeignete Abkürzungen, damit Ihr sie wiederfindet oder kommentiert sie.
Das
Beispielsweise bei
Bei der Property Value wird der Wert gesetzt und anschließend invalidiert. Das heißt, es wird der Bereich neu gezeichnet, wenn sich die Value ändert.
Der Vorteil von
Für andere Properties, die Ihr erstellen wollt, macht Ihr das genauso. Ich werde nachher noch eine Property machen, mit der Ihr die Farbe des Balkens ändern könnt.
Der Rest sollte klar sein.
So, nun gehen wir zum letzten wichtigen (sogar wichtigsten) Schritt beim Erstellen des Controls.
Wir zeichnen die ProgressBar in der OnPaint-Methode.
Schließlich folgen noch ein paar Sachen. Das
Da kommt noch das:
Anschließend fügen wir noch ein paar GDI-Einstellungen hinzu, damit wir eine gute Qualität bekommen.
Alles was nun folgt wird mit
So, damit haben wir die höchsten Einstellungen, die die beste Grafik zeichnen werden.
Zu guter Letzt folgt jetzt das Zeichnen der ProgressBar:
Ok... Nach diesem großen Code hat unsere ProgressBar alles nötige und funktioniert nun. Lest euch den Code in Ruhe durch und versucht ihn zu verstehen.
Ich gebe zu, dass man die Variablen zuvor hätte deklarieren müssen und den Rest in ein eigenes Sub packen. (Keine Sorge, bei meinen Projekten mache ich das auch so). Es ist halt nur hier der Übersicht zu Gute, damit man alles an einem Fleck hat.
Wie binde ich die ProgressBar ein bzw. starte sie?
Dazu benötigen wir natürlich ein neues Projekt (WinForms-Anwendung).
Wenn Ihr eins erstellt habt, dann klickt im Menü oben auf
Nun klickt Ihr auf
Nun habt Ihr sie in der Toolbox. Zieht sie auf die Form, fügt einen Timer hinzu (Interval egal) und geht in den Code-Editor.
Im Load-Event schreibt Ihr:
Im Timer1_Tick-Event:
Mir ist natürlich bewusst, dass dies Pseudo-Code ist. Es dient hier rein zur Veranschaulichung der ProgressBar.
Klickt auf "Debuggen" und Ihr seht eure eigene ProgressBar flüssig und ohne Flackern druchlaufen.
Wie kann ich nun die Farbe des Balkens ändern lassen?
Dies ist garnicht schwer. Wir brauchen nur eine weitere Property.
Ich nenne diese:
Um nun die Property aufzurufen und die Farbe zu ändern müssen wir
Das ist alles.
Wie bekommt mein Control in der Toolbox die ProgressBar-Bitmap?
Dazu schreiben wir über
Okay, ich habe nochmal eine ZIP-Datei mit dem Ganzen angehängt, allerdings übersichtlicher und in eigenen Subs.
Die hier gezeigten Codeteile sind natürlich zu verbessern, allerdings wäre dann die Übersicht des Tutorials in die Hose gegangen.
Wenn Ihr noch Fehler findet, dann berichtet diese bitte.
lg Trade
PS: Ich hänge in Teil2 nochmal den kompletten Code an
da mir langweilig war wollte ich mich mal einem kleinen Tutorial widmen. Dies erfordert natürlich grundlegende Kenntnisse in VB.NET und Klassenbibliotheken.
Ich wollte mich speziell darauf spezialisieren wie man Controls flüssig laufend erstellen kann. Als Beispiel nehmen wir eine ProgressBar als Control. Zwar gab es dazu schon mal einen Thread, aber dieser hatte Codeteile, die nicht mehr aktuell sind bzw. Nachteile haben.
Vorwort:
- Bevor wir loslegen gibt es zu sagen, dass wir nur GDI+ für unser Control verwenden werden. Also keine Bilder oder sonstiges, da
a) das unsauber und schlechte Programierung ist
b) man an das Bild gebunden ist. (Mit GDI+ kann man mehr machen)
c) bei einer ProgressBar sowas garnicht möglich ist
Wenn Ihr neu in GDI+ seid, dann schaut euch das Tutorial von @FreakJNS: an.
[VB 2008] [Tutorial] GDI+
- Dies soll nicht als C&P-Quelle dienen, sondern als grundlegendes Tutorial zum flüssigen Erstellen von Controls.
Los geht's
So, wir erstellen nun einfach mal eine simple ProgressBar.
Diese wird einen Hintergrund besitzen und einen einfachen Balken. Ihr könnt natürlich mehr Effekte adden, indem Ihr HatchStyles etc benutzt. Steht alles im Tutorial, was ich oben gepostet habe.
Zudem müsst Ihr dann bei manchen Sachen Änderungen vornehmen.

Also wir erstellen uns erstmal ein neues Projekt in Visual Studio (Visual Basic).
Dazu wählen wir Visual Basic als Programmiersprache aus (wenn Ihr VB als IDE habt und nicht VS, dann fällt dieser Schritt weg) und schließlich als Typ:
Klassenbibliothek
. Gebt einen Namen ein (wir nehmen hier mal TestBar
) und klickt auf "Erstellen".So nun haben wir eine Klasse in unserem Projekt, die heißt standardmäßig
Class1
. Um diese nun umzubenennen in den Namen unseres Projekts geht Ihr in den Projektmappen-Explorer: 
Dieser befindet sich im Projekt rechts oben.
Dann macht Ihr einen Doppelklick auf die Class1 und könnt nun einen neuen Namen hineinschreiben. Bestätigt Eure Eingabe mit
Enter
und klickt bei der kommenden Meldung auf Ja
.So, nun haben wir das Ganze umbenannt. Alles was jetzt in unserer Klasse steht ist:
So, um nun ein Control zu erstellen müssen wir vom Control erben. Damit dies funktioniert fehlt uns ein Imports-Anweisung.
Für GDI+ benötigen wir übrigens noch mehr, darum fasse ich gleich alle zusammen. Diese fügt Ihr über
Public Class TestBar
ein.Ich füge dort auch noch die Anweisung für
Option Strict
ein. Diese sollte bei euch schon als Standard auf "On" stehen. Wenn Ihr nicht wisst was das ist: Klick michSo, das sieht nun so aus:
VB.NET-Quellcode
- Option Strict On
- Imports System.Windows.Forms 'Dies brauchen wir für das "Control", da dies zu Windows.Forms gehört
- Imports System.Drawing 'Brauchen wir für GDI+
- Imports System.Drawing2D 'Brauchen wir für Brushes etc.
- Imports System.Drawing.Text 'Brauchen wir für TextRendering
- Public Class TestBar
- End Class
Ok, nun können wir loslegen. Wir lassen unsere Klasse nun von
Control
erben.Warum nicht
ProgressBar
?Ganz einfach. Wenn wir von ProgressBar erben haben wir zwar schon unsere Eigenschaften, wie Value etc., die wir mit
MyBase.Value
aufrufen können, jedoch wenn wir eigene Sachen implementieren wollen und unsere ProgressBar Änderungen hat, die nicht der normalen entsprechen, dann haben wir das Problem, dass wir all die nicht passenden Properties etc als Shadows
deklarieren müssen, um sie zu verdecken. Wenn dann aber unsere Klasse zurück gecastet wird sind diese wieder sichtbar. Es besteht auch die Möglichkeit das Ganze als Overrides
zu deklarieren und sie zu überschreiben, aber die meisten unterstützen keine Polymorphie und sind nicht als Overridable
deklariert, sodass das im Grunde ziemlich blöd ist. Also erben wir vom
Control
. Die Sachen wie Value etc. müssen eh berechnet werden...Dazu schreiben wir unter
Public Class TestBar
:So, bei manchen kann jetzt ein Fehler kommen. Wenn dies der Fall ist, dann nutzt einfach die Möglichkeit von Visual Studio, klickt doppelt auf den Fehler und wählt den Korrekturvorschlag.
So, nun müssen wir wie für jedes Control, das erbt, einen Konstruktor angeben. Dies geschieht mit
New()
. In diesen Konstruktor können auch die Eigenschaften wie Size, denn wenn Ihr die ProgressBar später auf die Form zieht, dann wird dieser zuerst aufgerufen. NICHT IntializeComponent()
.In diesem Konstruktor wird nun unser Control erstellt:
Nun folgen die Einstellungen zur Qualität, damit das Ganze flüssig und ohne flackern läuft.
Dies sind die Einstellungen, die am Besten geeignet sind. Wichtig ist auf jeden Fall hauptsächlich:
Me.DoubleBuffered = True
.Wichtig: Dies kommt auf keinen Fall ins OnPaint, sondern immer in den Konstruktor. Danke @Artentus: für den Tipp.
Ihr könnt noch optional
Me.SuspendLayout()
und schließlich Me.ResumeLayout(False)
einfügen. Damit wird beim Zeichnen einfach die ProgressBar kurz "eingefroren", sodass Einstellungen wie Size
etc. übernommen werden und danach wird das Ganze freigegeben. So.
Das wäre alles wichtige. Nun kommt das Zeichnen der ProgressBar selbst und Sachen wie Properties.
Ich rate euch für eure Properties, Functions etc eigene Regions zu erstellen. Dies geht mit:
Der Übersicht zu Liebe. Okay, um nun Sachen wie
Value
usw bereitzustellen benötigen wir ein paar Properties:VB.NET-Quellcode
- Dim max As Integer = 100
- <Category("Werte")>
- Public Property Maximum() As Integer
- Get
- Return max
- End Get
- Set(ByVal value As Integer)
- max = value
- Me.Invalidate()
- End Set
- End Property
- Dim min As Integer = 0
- <Category("Werte")>
- Public Property Minimum() As Integer
- Get
- Return min
- End Get
- Set(ByVal value As Integer)
- min = value
- Me.Invalidate()
- End Set
- End Property
- Dim val As Integer = 70
- <Category("Werte")>
- Public Property Value() As Integer
- Get
- Return val
- End Get
- Set(ByVal value As Integer)
- val = value
- Me.Invalidate()
- End Set
- End Property
Erklärung:
Die Variablen, die wir hier erstellen dienen dazu einen Standardwert zu geben.
Bei Maximum ist dieser beispielsweise 100. Ihr könnt aber auch 50 nehmen, oder was Euch halt gefällt.
Nehmt für die Variablenamen immer geeignete Abkürzungen, damit Ihr sie wiederfindet oder kommentiert sie.
Das
<Category("Werte")>
erstellt für die Property eine neue Kategorie im Eigenschaftsfenster. Ihr könnt diese auch in bereits vorhandenen einordnen.Beispielsweise bei
Verhalten.
Dann schreibt Ihr: <Category("Verhalten")>
.Bei der Property Value wird der Wert gesetzt und anschließend invalidiert. Das heißt, es wird der Bereich neu gezeichnet, wenn sich die Value ändert.
Der Vorteil von
Me.Invalidate()
ist, dass man in den Parametern genaue Bereiche angeben kann.Für andere Properties, die Ihr erstellen wollt, macht Ihr das genauso. Ich werde nachher noch eine Property machen, mit der Ihr die Farbe des Balkens ändern könnt.
Der Rest sollte klar sein.
So, nun gehen wir zum letzten wichtigen (sogar wichtigsten) Schritt beim Erstellen des Controls.
Wir zeichnen die ProgressBar in der OnPaint-Methode.
Schließlich folgen noch ein paar Sachen. Das
OnPaintBackground
kann auch als selbiges behandelt werden. Ich hab das hier nicht gemacht.Da kommt noch das:
Anschließend fügen wir noch ein paar GDI-Einstellungen hinzu, damit wir eine gute Qualität bekommen.
Alles was nun folgt wird mit
e.Graphics
gemacht. Also verwenden wir die With
-Anweisung.So, damit haben wir die höchsten Einstellungen, die die beste Grafik zeichnen werden.
Zu guter Letzt folgt jetzt das Zeichnen der ProgressBar:
VB.NET-Quellcode
- Dim HintergrundHoehe As Integer = MyBase.ClientRectangle.Height
- 'Die Höhe des Hintergrunds
- Dim HintergrundBreite As Integer = MyBase.ClientRectangle.Width
- 'Die Breite des Hntergrunds
- Dim BalkenHoehe As Integer = CInt(MyBase.ClientRectangle.Height)
- 'Die Höhe des Balken (entspricht der Höhe des Hintergrunds)
- Dim BalkenBreite As Integer = Width * (Value - Minimum) \ (Maximum - Minimum)
- 'Die Value ändert sich dann immer und das Ganze wird neu berechnet, sodass der Balken länger wird
- Dim Hintergrundfarbe As Color = Color.White
- 'Wir setzen die Hintergrundfarbe auf weiß. (benutzerdefiniert)
- Dim Balkenfarbe As Color = Me.BalkenColor
- 'Wir setzen die Balkenfarbe auf grün (benutzerdefiniert)
- Dim hintergrundrect As New Rectangle(0, 0, HintergrundBreite, HintergrundHoehe)
- 'Wir erstellen ein neues Rectangle mit der Location (0,0) und den Werten der oben deklarierten Variablen
- .FillRectangle(New SolidBrush(Hintergrundfarbe), hintergrundrect)
- 'Wir füllen das Rectangle mit einer SolidBrush (festen Farbe)
- Dim balkenrect As New Rectangle(0, 0, BalkenBreite, BalkenHoehe)
- 'Wir erstellen ein neues Rectangle für den Balken mit der Location (0,0) und den Werten der oben deklarierten Variablen
- .FillRectangle(New SolidBrush(Balkenfarbe), balkenrect)
- 'Wir füllen das Rectangle wieder mit einer SolidBrush (festen Farbe)
- End With
Ok... Nach diesem großen Code hat unsere ProgressBar alles nötige und funktioniert nun. Lest euch den Code in Ruhe durch und versucht ihn zu verstehen.
Ich gebe zu, dass man die Variablen zuvor hätte deklarieren müssen und den Rest in ein eigenes Sub packen. (Keine Sorge, bei meinen Projekten mache ich das auch so). Es ist halt nur hier der Übersicht zu Gute, damit man alles an einem Fleck hat.
Wie binde ich die ProgressBar ein bzw. starte sie?
Dazu benötigen wir natürlich ein neues Projekt (WinForms-Anwendung).
Wenn Ihr eins erstellt habt, dann klickt im Menü oben auf
Extras
und dann Werkzeugkastenelemente auswählen...
.Nun klickt Ihr auf
Durchsuchen...
, wählt die .dll aus und klickt auf OK
.Nun habt Ihr sie in der Toolbox. Zieht sie auf die Form, fügt einen Timer hinzu (Interval egal) und geht in den Code-Editor.
Im Load-Event schreibt Ihr:
Im Timer1_Tick-Event:
Mir ist natürlich bewusst, dass dies Pseudo-Code ist. Es dient hier rein zur Veranschaulichung der ProgressBar.
Klickt auf "Debuggen" und Ihr seht eure eigene ProgressBar flüssig und ohne Flackern druchlaufen.
Wie kann ich nun die Farbe des Balkens ändern lassen?
Dies ist garnicht schwer. Wir brauchen nur eine weitere Property.
Ich nenne diese:
BalkenColor
und gebe Ihr in einer Variable den Standardwert: Green
Um nun die Property aufzurufen und die Farbe zu ändern müssen wir
Dim Balkenfarbe As Color = Color.Green
zu Dim Balkenfarbe As Color = Me.BalkenColor
ändern. Heißt, dass die Balkenfarbe von der Property abhängig ist. Sobald sich der Wert dieser Eigenschaft ändert, wechselt die Farbe.Das ist alles.
Wie bekommt mein Control in der Toolbox die ProgressBar-Bitmap?
Dazu schreiben wir über
Public Class TestBar
: <ToolboxBitmap(GetType(ProgressBar))> _
Okay, ich habe nochmal eine ZIP-Datei mit dem Ganzen angehängt, allerdings übersichtlicher und in eigenen Subs.
Die hier gezeigten Codeteile sind natürlich zu verbessern, allerdings wäre dann die Übersicht des Tutorials in die Hose gegangen.
Wenn Ihr noch Fehler findet, dann berichtet diese bitte.
lg Trade
PS: Ich hänge in Teil2 nochmal den kompletten Code an
#define for for(int z=0;z<2;++z)for // Have fun!
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!

Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da

Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von „Trade“ ()