Gewusst wie: Entwickeln eines einfachen Windows Forms-Steuerelements
Aktualisiert: November 2007
In diesem Abschnitt werden die wesentlichen Schritte beim Erstellen benutzerdefinierter Windows Forms-Steuerelemente behandelt. In dieser exemplarischen Vorgehensweise wird ein einfaches Steuerelement entwickelt, das die Änderung der Ausrichtung seiner Text-Eigenschaft zulässt. Es dient nicht zum Behandeln oder Auslösen von Ereignissen.
So erstellen Sie ein einfaches benutzerdefiniertes Steuerelement
Definieren Sie eine Klasse, die sich von System.Windows.Forms.Control ableitet.
Public Class FirstControl Inherits Control End Class
public class FirstControl:Control{}
Definieren Sie Eigenschaften. (Die Definition von Eigenschaften ist nicht zwingend erforderlich, da ein Steuerelement viele Eigenschaften von der Control-Klasse erbt. Jedoch definieren im Allgemeinen die meisten benutzerdefinierten Steuerelemente zusätzliche Eigenschaften.) Im folgenden Codefragment wird eine Eigenschaft mit dem Namen TextAlignment definiert. Sie wird von FirstControl dazu verwendet, die Anzeige der Text-Eigenschaft zu formatieren, die von Control geerbt wurde. Weitere Informationen über das Definieren von Eigenschaften finden Sie unter Übersicht über Eigenschaften.
' ContentAlignment is an enumeration defined in the System.Drawing ' namespace that specifies the alignment of content on a drawing ' surface. Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft <Category("Alignment"), Description("Specifies the alignment of text.")> _ Public Property TextAlignment() As ContentAlignment Get Return alignmentValue End Get Set alignmentValue = value ' The Invalidate method invokes the OnPaint method described ' in step 3. Invalidate() End Set End Property
// ContentAlignment is an enumeration defined in the System.Drawing // namespace that specifies the alignment of content on a drawing // surface. private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
Wenn Sie eine Eigenschaft festlegen, durch die die visuelle Darstellung eines Steuerelements geändert wird, müssen Sie die Invalidate-Methode aufrufen, um das Steuerelement neu zu zeichnen. Invalidate ist in der Basisklasse Control definiert.
Überschreiben Sie die geschützte, von Control geerbte OnPaint-Methode, um dem Steuerelement Wiedergabelogik zur Verfügung zu stellen. Wenn Sie OnPaint nicht überschreiben, wird das Steuerelement nicht in die Lage versetzt, sich selbst zu zeichnen. Im folgenden Codefragment zeigt die OnPaint-Methode die von Control geerbte Text-Eigenschaft mit der durch das alignmentValue-Feld festgelegten Ausrichtung an.
Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) Dim style As New StringFormat() style.Alignment = StringAlignment.Near Select Case alignmentValue Case ContentAlignment.MiddleLeft style.Alignment = StringAlignment.Near Case ContentAlignment.MiddleRight style.Alignment = StringAlignment.Far Case ContentAlignment.MiddleCenter style.Alignment = StringAlignment.Center End Select ' Call the DrawString method of the System.Drawing class to write ' text. Text and ClientRectangle are properties inherited from ' Control. e.Graphics.DrawString( _ me.Text, _ me.Font, _ New SolidBrush(ForeColor), _ RectangleF.op_Implicit(ClientRectangle), _ style) End Sub
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); StringFormat style = new StringFormat(); style.Alignment = StringAlignment.Near; switch (alignmentValue) { case ContentAlignment.MiddleLeft: style.Alignment = StringAlignment.Near; break; case ContentAlignment.MiddleRight: style.Alignment = StringAlignment.Far; break; case ContentAlignment.MiddleCenter: style.Alignment = StringAlignment.Center; break; } // Call the DrawString method of the System.Drawing class to write // text. Text and ClientRectangle are properties inherited from // Control. e.Graphics.DrawString( Text, Font, new SolidBrush(ForeColor), ClientRectangle, style); }
Stellen Sie Attribute für das Steuerelement bereit. Durch Attribute kann das Steuerelement samt seiner Eigenschaften und Ereignisse zur Entwurfszeit in einem visuellen Designer entsprechend angezeigt werden. Im folgenden Codefragment werden Attribute auf die TextAlignment-Eigenschaft angewendet. Das Category-Attribut (das im Codefragment gezeigt wird) führt in einem Designer wie Visual Studio dazu, dass die Eigenschaft in einer logischen Kategorie angezeigt wird. Das Description-Attribut bewirkt bei Auswahl der TextAlignment-Eigenschaft, dass eine beschreibende Zeichenfolge am unteren Rand des Eigenschaftenfensters angezeigt wird. Weitere Informationen über Attribute finden Sie unter Entwurfszeitattribute für Komponenten.
<Category("Alignment"), Description("Specifies the alignment of text.")> _ Public Property TextAlignment() As ContentAlignment
[ Category("Alignment"), Description("Specifies the alignment of text.") ]
(Optional) Stellen Sie Ressourcen für das Steuerelement bereit. Sie können dem Steuerelement eine Ressource (z. B. eine Bitmap) zur Verfügung stellen, indem Sie eine Compileroption (/res für C#) zum Verpacken von Ressourcen mit dem Steuerelement verwenden. Zur Laufzeit kann die Ressource mit den Methoden der ResourceManager-Klasse abgerufen werden. Weitere Informationen über das Erstellen und Verwenden von Ressourcen finden Sie unter Ressourcen in Anwendungen.
Kompilieren Sie das Steuerelement, und geben Sie es weiter. Zum Kompilieren und zur Bereitstellung von FirstControl führen Sie folgende Schritte aus:
Speichern Sie den Code im folgenden Beispiel als Quelldatei (z. B. als FirstControl.cs oder FirstControl.vb).
Kompilieren Sie den Quellcode in eine Assembly, und speichern Sie diese im Anwendungsverzeichnis. Führen Sie dazu den folgenden Befehl im Verzeichnis aus, das die Quelldatei enthält.
vbc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.vb
csc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.cs
Durch die Compileroption /t:library wird dem Compiler mitgeteilt, dass es sich bei der von Ihnen erstellten Assembly um eine Bibliothek und nicht um eine ausführbare Datei handelt. Durch die Option /out werden Pfad und Name der Assembly festgelegt. Die Option /r stellt den Namen der Assemblys bereit, auf die der Code verweist. In diesem Beispiel erstellen Sie eine private Assembly, die ausschließlich Ihre Anwendung verwenden kann. Daher müssen Sie sie in Ihrem Anwendungsverzeichnis speichern. Weitere Informationen über das Packen und Bereitstellen eines Steuerelements zur Verteilung finden Sie unter Bereitstellen von .NET Framework-Anwendungen.
Im Folgenden wird der Code für FirstControl gezeigt. Das Steuerelement ist im Namespace CustomWinControls eingeschlossen. Ein Namespace stellt eine logische Gruppe verwandter Typen bereit. Sie können ein Steuerelement in einem neuen oder vorhandenen Namespace erstellen. Using-Deklarationen (Imports in Visual Basic) ermöglichen in C# den Zugriff auf Typen über einen Namespace ohne Verwendung des vollständigen Typnamens. Im folgenden Beispiel ermöglicht es die using-Deklaration, dass Code die Control-Klasse aus System.Windows.Forms einfach als Control aufrufen kann, anstatt den vollständig qualifizierten Namen System.Windows.Forms.Control verwenden zu müssen.
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class FirstControl
Inherits Control
Public Sub New()
End Sub
' ContentAlignment is an enumeration defined in the System.Drawing
' namespace that specifies the alignment of content on a drawing
' surface.
Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
<Category("Alignment"), Description("Specifies the alignment of text.")> _
Public Property TextAlignment() As ContentAlignment
Get
Return alignmentValue
End Get
Set
alignmentValue = value
' The Invalidate method invokes the OnPaint method described
' in step 3.
Invalidate()
End Set
End Property
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
Dim style As New StringFormat()
style.Alignment = StringAlignment.Near
Select Case alignmentValue
Case ContentAlignment.MiddleLeft
style.Alignment = StringAlignment.Near
Case ContentAlignment.MiddleRight
style.Alignment = StringAlignment.Far
Case ContentAlignment.MiddleCenter
style.Alignment = StringAlignment.Center
End Select
' Call the DrawString method of the System.Drawing class to write
' text. Text and ClientRectangle are properties inherited from
' Control.
e.Graphics.DrawString( _
me.Text, _
me.Font, _
New SolidBrush(ForeColor), _
RectangleF.op_Implicit(ClientRectangle), _
style)
End Sub
End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace CustomWinControls
{
public class FirstControl : Control
{
public FirstControl()
{
}
// ContentAlignment is an enumeration defined in the System.Drawing
// namespace that specifies the alignment of content on a drawing
// surface.
private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
[
Category("Alignment"),
Description("Specifies the alignment of text.")
]
public ContentAlignment TextAlignment
{
get
{
return alignmentValue;
}
set
{
alignmentValue = value;
// The Invalidate method invokes the OnPaint method described
// in step 3.
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
StringFormat style = new StringFormat();
style.Alignment = StringAlignment.Near;
switch (alignmentValue)
{
case ContentAlignment.MiddleLeft:
style.Alignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleRight:
style.Alignment = StringAlignment.Far;
break;
case ContentAlignment.MiddleCenter:
style.Alignment = StringAlignment.Center;
break;
}
// Call the DrawString method of the System.Drawing class to write
// text. Text and ClientRectangle are properties inherited from
// Control.
e.Graphics.DrawString(
Text,
Font,
new SolidBrush(ForeColor),
ClientRectangle, style);
}
}
}
Verwenden des benutzerdefinierten Steuerelements in einem Formular
Im folgenden Beispiel wird ein einfaches Formular gezeigt, das FirstControl verwendet. Es werden drei Instanzen von FirstControl mit unterschiedlichen Werten für die TextAlignment-Eigenschaft erstellt.
So kompilieren Sie dieses Beispiel und führen es aus
Speichern Sie den Code im folgenden Beispiel als Quelldatei (SimpleForm.cs oder SimpleForms.vb).
Kompilieren Sie den Quellcode in eine ausführbare Assembly. Führen Sie dazu den folgenden Befehl in dem Verzeichnis aus, das die Quelldatei enthält.
vbc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.vb
csc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.cs
CustomWinControls.dll ist die Assembly, in der die Klasse FirstControl enthalten ist. Diese Assembly muss sich im selben Verzeichnis befinden wie die Quelldatei des Formulars, das auf sie zugreift (SimpleForm.cs oder SimpleForms.vb).
Führen Sie SimpleForm.exe mit folgendem Befehl aus.
SimpleForm
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class SimpleForm
Inherits System.Windows.Forms.Form
Private firstControl1 As FirstControl
Private components As System.ComponentModel.Container = Nothing
Public Sub New()
InitializeComponent()
End Sub
Private Sub InitializeComponent()
Me.firstControl1 = New FirstControl()
Me.SuspendLayout()
'
' firstControl1
'
Me.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark
Me.firstControl1.Location = New System.Drawing.Point(96, 104)
Me.firstControl1.Name = "firstControl1"
Me.firstControl1.Size = New System.Drawing.Size(75, 16)
Me.firstControl1.TabIndex = 0
Me.firstControl1.Text = "Hello World"
Me.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter
'
' SimpleForm
'
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(firstControl1)
Me.Name = "SimpleForm"
Me.Text = "SimpleForm"
Me.ResumeLayout(False)
End Sub
<STAThread()> _
Shared Sub Main()
Application.Run(New SimpleForm())
End Sub
End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace CustomWinControls
{
public class SimpleForm : System.Windows.Forms.Form
{
private FirstControl firstControl1;
private System.ComponentModel.Container components = null;
public SimpleForm()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.firstControl1 = new FirstControl();
this.SuspendLayout();
//
// firstControl1
//
this.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark;
this.firstControl1.Location = new System.Drawing.Point(96, 104);
this.firstControl1.Name = "firstControl1";
this.firstControl1.Size = new System.Drawing.Size(75, 16);
this.firstControl1.TabIndex = 0;
this.firstControl1.Text = "Hello World";
this.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
//
// SimpleForm
//
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.firstControl1);
this.Name = "SimpleForm";
this.Text = "SimpleForm";
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.Run(new SimpleForm());
}
}
}
Siehe auch
Konzepte
Ereignisse in Windows Forms-Steuerelementen