Zur Feier meines 1000. Beitrages dachte ich mir es wird mal wieder Zeit für ein Tutorial,
und da diese Frage auch des öfteren gestellt wird, habe ich mir die Zeit genommen eine kleine Erklärung dazu zu verfassen.
Natürlich werden für die erfolgreiche Ausführung diverse Grundkenntnisse benötigt.
Was benötigen Sie?
Für dieses Tutorial benötigen Sie keine besonderen Komponenten, lediglich ein Control,
dass Sie mit einer Actionlist bzw. dem ControlDesigner erweitern wollen.
Für dieses Tutorial verwende ich folgendes TestControl:
Spoiler anzeigen
Was ist eine Actionlist?
Als Actionlist bezeichnet man das Menü, dass sich beim Klicken auf das kleine Dreieck in der oberen rechten Ecke öffnet.
Hier sieht man die Actionlist am Beispiel eines meiner Controls:
Ebenfalls sieht man auf der Abbildung, dass man das Control nur nach links bzw. rechts vergrößern kann.
Dies wurde mit Hilfe der Control-Designer-Klasse bewerkstelligt.
Los geht's!
Zusätzlich zu unser Control-Klasse erstellen wir uns jetzt eine zusätzliche Designer-Klasse.
Der Name dieser Klasse ist grundsätzlich egal und kann variieren, jedoch ist es klug diesen mit dem Haupt-Control abzustimmen.
Meine Klasse trägt den Namen:
Als nächstes definieren wir uns noch eine Liste mit
Mit dem nächsten Schritt geben wir an, zu welchem Control der Designer gehört:
Nun fügen wir zu dem Designer die besagte Actionlist hinzu.
Dies geschieht ebenfalls anhand einer simplen Eigenschaft:
Fürs erste wäre es das, da wir nun schon eine ActionList zu unserem Control hinzugefügt haben.
Dennoch will ich ebenfalls noch ein paar zusätzliche Eigenschaften und Sub's, hinzufügen die ebenfalls sehr hilfreich sind.
Zusätzliche Funktionen
Zum Einen möchte ich nun erläutern, wie man dem Control die Richtungen vorgeben kann, in die es vergrößert bzw. verkleinert werden kann.
Dazu fügen wir ebenfalls zu der ControlDesigner-Klasse eine neue Eigenschaft hinzu. Die Eigentschaft
Dies ist ein Beispiel, und setzt die SelectionRules auf
Folgende Enum-Werte kann man der SelectionRules Variabel zuweisen:
Um z.B. kein verändern der Größe zu erlauben müssen Sie simpel den Wert der
Eine ebenfalls sehr hilfreiche Funktion des ControlDesigners ist, dass man einfach Eigenschaften entfernen kann.
Dies wird mit folgendem Code bewerkstelligt:
Verwendung der ActionList
Kommen wir nun zu dem Teil in dem ich Ihnen zeigen möchte, wie Sie ihr Control mit einer ActionList erweitern können.
Dies geschieht ebenfalls über eine Klasse. Wie schon vorhin bei der Designerklasse können Sie diese ebenfalls beliebig benennen, jedoch empfehle ich Ihnen diese ebenfalls wie ich
Dieser Klasse vererben wir aus
Anschließend erstellen wir zwei Privates:
Der nächste Schritt is der, in dem der ActionList das TestControl zugewiesen wird. Dies geschieht in der
Im Großen und Ganzen sind wir nun fast fertig, und Sie können gleich ihre ActionList verwenden. Jedoch müssen wir in der ActionList-Klasse nochmals die Eigenschaften deklarieren und erstellen, die unser HostControl besitzt und die in die ActionList eingebaut werden sollen. Diese wären in meinem Fall
Diese erstelle ich einfach genau gleich wie in der Hauptklasse des Controls:
Ebenfalls möchte ich Ihnen nun zeigen, wie Sie eine Sub via der ActionList aufrufen können.
Dazu erstellen wir einfach eine simple Sub. In meinem Fall vertauscht diese die Werte der beiden Eigenschaften mit einander.
Kommen wir nun zum Abschluss des Ganzen. Wir fügen die zwei Eigenschaften und die einzelne Sub zu der ActionList hinzu.
Dazu erstellen wir eine Funktion die die
Diese Funktion sollte sich eigentlich von selbst erklären, dennoch möchte ich sie noch etwas erläutern:
Heißt, dem Namen der Property, dem Anzeigenamen, der Kategorie und einer einfachen Beschreibung.
Das Hinzufügen der Sub funktioniert grundsätzlich genau gleich bis auf eine kleine Veränderung:
Bevor man die Methode angibt, muss man noch die ActionList auswählen zu der die Methode gehört. Und dies ist in unserem Fall logischerweise
Das war's!
Und schon wurde Ihr Control um eine ActionList und andere hilfreiche Funktionen erweitert.
Ich hoffe sehr, dass ich Ihnen damit weiterhelfen konnte.
Natürlich habe ich zum Schluss noch ein paar Downloads hinzugefügt, die Sie ebenfalls als Lernhilfe bzw. Veranschaulichungsmaterial verwenden können.
Mit freundlichen Grüßen
Martin Pfeiffer (Gather)
und da diese Frage auch des öfteren gestellt wird, habe ich mir die Zeit genommen eine kleine Erklärung dazu zu verfassen.
Natürlich werden für die erfolgreiche Ausführung diverse Grundkenntnisse benötigt.
Was benötigen Sie?
Für dieses Tutorial benötigen Sie keine besonderen Komponenten, lediglich ein Control,
dass Sie mit einer Actionlist bzw. dem ControlDesigner erweitern wollen.
Für dieses Tutorial verwende ich folgendes TestControl:
VB.NET-Quellcode
- <Designer(GetType(TestControlDesigner))>
- Public Class TestControl
- Inherits Control
- #Region "Declarations"
- ''' <summary>
- ''' Wird für die Angabe des Aktuellen Mausstatus benötigt.
- ''' </summary>
- ''' <remarks></remarks>
- Private CurrentState As MouseState = MouseState.None
- #End Region
- #Region "Enumerations"
- ''' <summary>
- ''' Enum für die Angabe des aktuellen Mausstatus.
- ''' </summary>
- ''' <remarks></remarks>
- Enum MouseState
- None = 0
- Over = 1
- Down = 2
- End Enum
- #End Region
- #Region "Sub-Area"
- Protected Overrides Sub OnMouseEnter(e As System.EventArgs)
- CurrentState = MouseState.Over
- Invalidate()
- MyBase.OnMouseEnter(e)
- End Sub
- Protected Overrides Sub OnMouseLeave(e As System.EventArgs)
- CurrentState = MouseState.None
- Invalidate()
- MyBase.OnMouseLeave(e)
- End Sub
- Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
- CurrentState = MouseState.Down
- Invalidate()
- MyBase.OnMouseDown(e)
- End Sub
- Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
- CurrentState = MouseState.Over
- Invalidate()
- MyBase.OnMouseUp(e)
- End Sub
- Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
- Dim G As Graphics = e.Graphics
- Select Case CurrentState
- Case MouseState.None
- G.DrawRectangle(New Pen(Brushes.Green), New Rectangle(0, 0, Width - 1, Height - 1))
- Case MouseState.Over
- G.DrawRectangle(New Pen(Brushes.Yellow), New Rectangle(0, 0, Width - 1, Height - 1))
- Case MouseState.Down
- G.DrawRectangle(New Pen(Brushes.Red), New Rectangle(0, 0, Width - 1, Height - 1))
- End Select
- MyBase.OnPaint(e)
- End Sub
- #End Region
- #Region "Properties"
- Private _TestpropertyOne As Integer = 5
- ''' <summary>
- ''' Einfache Testeigenschaft zur veranschaulichung der Actionlist.
- ''' </summary>
- <Description("Einfache Testeigenschaft zur veranschaulichung der Actionlist.")>
- <Category("Testing")>
- <DefaultValue(5)>
- Public Property TestpropertyOne As Integer
- Get
- Return _TestpropertyOne
- End Get
- Set(value As Integer)
- _TestpropertyOne = value
- End Set
- End Property
- Private _TestpropertyTwo As Integer = 10
- ''' <summary>
- ''' Einfache Testeigenschaft zur veranschaulichung der Actionlist.
- ''' </summary>
- <Description("Einfache Testeigenschaft zur veranschaulichung der Actionlist.")>
- <Category("Testing")>
- <DefaultValue(10)>
- Public Property TestpropertyTwo As Integer
- Get
- Return _TestpropertyTwo
- End Get
- Set(value As Integer)
- _TestpropertyTwo = value
- End Set
- End Property
- #End Region
- End Class
Was ist eine Actionlist?
Als Actionlist bezeichnet man das Menü, dass sich beim Klicken auf das kleine Dreieck in der oberen rechten Ecke öffnet.
Hier sieht man die Actionlist am Beispiel eines meiner Controls:
Ebenfalls sieht man auf der Abbildung, dass man das Control nur nach links bzw. rechts vergrößern kann.
Dies wurde mit Hilfe der Control-Designer-Klasse bewerkstelligt.
Los geht's!
Zusätzlich zu unser Control-Klasse erstellen wir uns jetzt eine zusätzliche Designer-Klasse.
Der Name dieser Klasse ist grundsätzlich egal und kann variieren, jedoch ist es klug diesen mit dem Haupt-Control abzustimmen.
Meine Klasse trägt den Namen:
TestControlDesigner
. Um diese Klasse nun zu einer ControlDesigner-Klasse zu machen, vererben wir ihr dies mit:Inherits System.Windows.Forms.Design.ControlDesigner
.Als nächstes definieren wir uns noch eine Liste mit
Private lists As DesignerActionListCollection
Mit dem nächsten Schritt geben wir an, zu welchem Control der Designer gehört:
Nun fügen wir zu dem Designer die besagte Actionlist hinzu.
Dies geschieht ebenfalls anhand einer simplen Eigenschaft:
VB.NET-Quellcode
Fürs erste wäre es das, da wir nun schon eine ActionList zu unserem Control hinzugefügt haben.
Dennoch will ich ebenfalls noch ein paar zusätzliche Eigenschaften und Sub's, hinzufügen die ebenfalls sehr hilfreich sind.
Zusätzliche Funktionen
Zum Einen möchte ich nun erläutern, wie man dem Control die Richtungen vorgeben kann, in die es vergrößert bzw. verkleinert werden kann.
Dazu fügen wir ebenfalls zu der ControlDesigner-Klasse eine neue Eigenschaft hinzu. Die Eigentschaft
SelectionRules
.VB.NET-Quellcode
- 'Bestimmt wie das Control vergrößert bzw. verkleinert werden kann.
- Public Overrides ReadOnly Property SelectionRules() As System.Windows.Forms.Design.SelectionRules
- Get
- Dim selRules As SelectionRules = Windows.Forms.Design.SelectionRules.Moveable
- selRules = selRules Or Windows.Forms.Design.SelectionRules.AllSizeable
- Return selRules
- End Get
- End Property
Dies ist ein Beispiel, und setzt die SelectionRules auf
AllSizable
und somit gibt es keinen Unterschied.Folgende Enum-Werte kann man der SelectionRules Variabel zuweisen:
Um z.B. kein verändern der Größe zu erlauben müssen Sie simpel den Wert der
selRules
Variabel auf folgendes ändern:selRules = selRules Or Windows.Forms.Design.SelectionRules.None
Eine ebenfalls sehr hilfreiche Funktion des ControlDesigners ist, dass man einfach Eigenschaften entfernen kann.
Dies wird mit folgendem Code bewerkstelligt:
VB.NET-Quellcode
- 'Entfern Eigenschaft auf dem Control.
- Protected Overrides Sub PostFilterProperties(ByVal properties As System.Collections.IDictionary)
- properties.Remove("BorderStyle")
- properties.Remove("RightToLeft")
- properties.Remove("Text")
- properties.Remove("ForeColor")
- properties.Remove("Font")
- MyBase.PostFilterProperties(properties)
- End Sub
Verwendung der ActionList
Kommen wir nun zu dem Teil in dem ich Ihnen zeigen möchte, wie Sie ihr Control mit einer ActionList erweitern können.
Dies geschieht ebenfalls über eine Klasse. Wie schon vorhin bei der Designerklasse können Sie diese ebenfalls beliebig benennen, jedoch empfehle ich Ihnen diese ebenfalls wie ich
TestControlActionList
zu nennen.Dieser Klasse vererben wir aus
DesignerActionList
mit Inherits DesignerActionList
.Anschließend erstellen wir zwei Privates:
Der nächste Schritt is der, in dem der ActionList das TestControl zugewiesen wird. Dies geschieht in der
Sub New
Im Großen und Ganzen sind wir nun fast fertig, und Sie können gleich ihre ActionList verwenden. Jedoch müssen wir in der ActionList-Klasse nochmals die Eigenschaften deklarieren und erstellen, die unser HostControl besitzt und die in die ActionList eingebaut werden sollen. Diese wären in meinem Fall
TestpropertyOne
und TestpropertyTwo
.Diese erstelle ich einfach genau gleich wie in der Hauptklasse des Controls:
VB.NET-Quellcode
- Public Property TestpropertyOne() As Integer
- Get
- Return _ctrl.TestpropertyOne
- End Get
- Set(ByVal value As Integer)
- _ctrl.TestpropertyOne = value
- End Set
- End Property
- Public Property TestpropertyTwo() As Integer
- Get
- Return _ctrl.TestpropertyTwo
- End Get
- Set(ByVal value As Integer)
- _ctrl.TestpropertyTwo = value
- End Set
- End Property
Ebenfalls möchte ich Ihnen nun zeigen, wie Sie eine Sub via der ActionList aufrufen können.
Dazu erstellen wir einfach eine simple Sub. In meinem Fall vertauscht diese die Werte der beiden Eigenschaften mit einander.
Kommen wir nun zum Abschluss des Ganzen. Wir fügen die zwei Eigenschaften und die einzelne Sub zu der ActionList hinzu.
Dazu erstellen wir eine Funktion die die
GetSortedActionItems
Funktion überschreibt:VB.NET-Quellcode
- Public Overrides Function GetSortedActionItems() As System.ComponentModel.Design.DesignerActionItemCollection
- Dim items As New DesignerActionItemCollection
- items.Add(New DesignerActionHeaderItem("Eigenschaften"))
- items.Add(New DesignerActionPropertyItem("TestpropertyOne", "TestpropertyOne:", "Eigenschaften", "Einfache Testeigenschaft zur veranschaulichung der Actionlist."))
- items.Add(New DesignerActionPropertyItem("TestpropertyTwo", "TestpropertyTwo:", "Eigenschaften", "Einfache Testeigenschaft zur veranschaulichung der Actionlist."))
- items.Add(New DesignerActionMethodItem(Me, "SwapValues", "Swap Values", "Eigenschaften", "Vertauscht die beiden Werte."))
- Return (items)
- End Function
Diese Funktion sollte sich eigentlich von selbst erklären, dennoch möchte ich sie noch etwas erläutern:
items.Add(New DesignerActionHeaderItem("Eigenschaften"))
erstellt eine einfache Überschrift.items.Add(New DesignerActionPropertyItem("TestpropertyOne", "TestpropertyOne:", "Eigenschaften", "Einfache Testeigenschaft zur veranschaulichung der Actionlist."))
besteht aus folgenden ObjektenHeißt, dem Namen der Property, dem Anzeigenamen, der Kategorie und einer einfachen Beschreibung.
Das Hinzufügen der Sub funktioniert grundsätzlich genau gleich bis auf eine kleine Veränderung:
Bevor man die Methode angibt, muss man noch die ActionList auswählen zu der die Methode gehört. Und dies ist in unserem Fall logischerweise
Me
.Das war's!
Und schon wurde Ihr Control um eine ActionList und andere hilfreiche Funktionen erweitert.
Ich hoffe sehr, dass ich Ihnen damit weiterhelfen konnte.
Natürlich habe ich zum Schluss noch ein paar Downloads hinzugefügt, die Sie ebenfalls als Lernhilfe bzw. Veranschaulichungsmaterial verwenden können.
Mit freundlichen Grüßen
Martin Pfeiffer (Gather)