Die häufigste Frage, die mir in den verschieden News-Groups über .NET aufgefallen ist, war die grundsätzliche Frage wie funktioniert die Vererbung nun an einem praktischen und kleinen Beispiel wirklich. Dabei wurde immer wieder gefragt: "...Ich habe eine Textbox und möchte dieser bestimmte Dinge beibringen, wie z.B. nur numerische Eingaben entgegenzunehmen, oder den Text immer in einem bestimmten Format anzeigen. Wie muss ich dabei vorgehen ?" Um diese Frage soll es hier gehen. Doch dies soll kein Aufsatz für Profi-Programmierer, sondern eine einfache Einführung für den absoluten VB.NET-Anfänger sein. Zuvor müssen jedoch dem angehenden Programmierer vier Dinge (zumindest in den Grundzügen) klar sein:
Dazu ebenfalls vier kurze (einfache) Antworten:
Ich weiß, dass das eine sehr extrem vereinfachte Darstellung ist, aber für den Anfang reicht das erst mal. Doch nun zurück zu unserer Textbox. Ich möchte am Beispiel dieser Textbox zeigen, wie man mit einer neuen "NumericTextbox (-klasse)", welche von der ursprünglichen "Textbox (-klasse)" geerbt hat, das grundlegende Eingabeverhalten aller "NumericTextbox-Objekte" in einem Programm beeinflussen kann. Also, Aufgabe soll sein, eine numerische Textbox zu erstellen, die:
Soweit die Anforderungen an die NumericTextbox-Klasse. Das Grundgerüst Doch nun "In Medias Res". (Eine Anmerkung sei noch gestattet: VB.NET nimmt Fehler in der Groß-/Kleinschreibung übel. Es ist also nicht egal ob der Name oder die Methode groß oder klein geschrieben wird.) Starten Sie die Visual Studio Entwicklungsumgebung und erstellen ein neues Projekt vom Typ Klassenbibliothek. Als Projektname geben Sie NumValueInputLib ein.
Klicken Sie anschließend im Projektmappen-Explorer mit der rechten Maustaste auf "Class1.vb" und benennen die neue Klasse NumValueInput.vb. Die Bezeichnung "Class1" im Codefenster ändern Sie ebenfalls: Public Class NumValueInput Da wir eine Klasse bilden wollen, welche den Ursprung in der Textbox hat, müssen wir zuerst festlegen wo das System nach dieser "Ursprungsklasse" suchen soll und dass sie von dieser erbt. Public Class NumValueInput ' Name der neuen Klasse ' erben von System.Windows.Forms.TextBox Inherits System.Windows.Forms.TextBox End Class ' Abschließen der Klassendefinition Um die TextBox der Windows.Forms Klasse verwenden zu können, muss die Komponente System.Windows.Forms dem Projekt als Verweis hinzugefügt werden. Klicken Sie im Projektmappen-Explorer hierzu mit der rechten Maustaste auf den Eintrag Verweise und wählen den Befehl Verweis hinzufügen. Im Dialogfeld Verweise hinzufügen doppelklicken Sie anschließend auf den Eintrag System.Windows.Forms.dll und klicken abschließend auf OK. Eigentlich haben wir jetzt schon das Grundgerüst für eine neue Textboxklasse fertig. Die würde sogar schon funktionieren, da sie ja alle Eigenheiten der originalen Textboxklasse geerbt hat. Aber wir wollen ja unsere eigenen Erweiterungen einführen. Also definieren wir uns eine Region "Propertys". So haben wir es später leichter, den Quelltext zu lesen. Danach die Variablen, welche innerhalb der Klasse die Werte der Eigenschaften aufnehmen sollen. #Region "Propertys" Private varValueNegativ As Boolean ' negative Zahlen erlaubt Ja/Nein #End Region Den Region-Block fügen Sie bitte direkt nach Inherits System.Windows.Forms.TextBox ein. Nun können wir mit der Definition der ersten Eigenschaft beginnen. (Die weiteren sind dem Quelltext der Klasse zu entnehmen.) Eine Eigenschaft besteht aus zwei Teilen, dem Teil der den Wert entgegen nimmt, und dem Teil der den Wert der Eigenschaft zurückgibt. Soll der Eigenschaft ein Anfangswert zugewiesen werden, so kann dies später, in der "NEW()-Methode" geschehen. Eingeleitet wird die Eigenschaftsdefinition mit dem Schlüsselwort Property. Davor wird festgelegt, ob die Eigenschaft nach außen sichtbar ist ("Public") oder nicht ("Private"). Außerdem wird der Typ der Eigenschaft bestimmt. Wir werden jetzt als Beispiel die Eigenschaft anlegen, welche die Eingabe von negativen Zahlen erlaubt ("True") oder verbietet ("False"). Sie hat also den Datentyp Boolean. Der "GET"-Teil gibt den Inhalt der Variablen varValueNegativ zurück, während der "SET"-Teil diese Variable mit dem Wert füllt. #Region "Propertys" Private varValueNegativ As Boolean ' negative Zahlen erlaubt Ja/Nein ' Negativ-Werte erlaubt? Public Property NegativValue() As Boolean Get Return varValueNegativ End Get Set(ByVal Value As Boolean) varValueNegativ = Value End Set End Property #End Region Unser neues Control hat jetzt eine neue Eigenschaft erhalten. Doch jetzt müssen wir diese auch noch in einer Methode entsprechend nutzen. Erstellen von Methoden Für die einzelnen Methoden fügen wir zur besseren Übersicht wiederum eine eigene Region ein und benennen diese My Code. In dieser Region erstellen wir eine Methode die, je nach der Einstellung in der Eigenschaft "NegativValue", die Eingabe negativer Zahlen akzeptiert oder ablehnt. #Region " My Code " Public Function CheckValue() As Boolean ' ***************************************************** ' * RETURN Boolean ' * True: Eingabe ist OK ' * False: Eingabe ist keine Zahl, oder die Vorgabe ' * von "NegativValue" wird nicht eingehalten ' ***************************************************** Dim lResume As Boolean Dim lNeg As Boolean lNeg = False If IsNumeric(Me.Text) Then If Not Me.NegativValue Then If System.Math.Sign(CDbl(Me.Text)) = -1 Then lNeg = True lResume = False Else lResume = True End If Else lResume = True End If Else lResume = False End If If lResume Then CheckValue = True Else If MsgBox(IIf(lNeg, "Negative Zahlen nicht erlaubt", _ "Nur Zahlen eingeben") & _ Chr(10) & Chr(13) & _ "Auf 0 setzen und weiter ?", MsgBoxStyle.YesNo + _ MsgBoxStyle.Exclamation, "Fehler") = MsgBoxResult.Yes Then Me.Text = "0" CheckValue = True Else CheckValue = False End If End If End Function #End Region Diese Methode binden wir nun an die OnValid-Methode. Hierbei wird mit Protected zuerst festgelegt, dass der Zugriff nur in der Klasse und davon abgeleiteten Klassen erfolgen darf. Danach wird mit Overrides die Originale Methode überschrieben. Am Ende sollte jedoch nicht der Aufruf der Original-Methode fehlen. Mit e wird das Abbruch-Ereignis festgelegt. #Region " My Code " ... ' Ruft die Check-Methode auf Protected Overrides Sub OnValidating( _ ByVal e As System.ComponentModel.CancelEventArgs) Dim lResume As Boolean ' Aufruf der Prüf-Methode lResume = Me.CheckValue ' Bei e.Cancel = False kann später das Objekt ' normal beendet werden, bei e.Cancel = True ' kann das Objekt nicht verlassen werden e.Cancel = Not lResume ' TextBox neuzeichnen Me.Refresh() ' Die Original-Methode von TextBox aufrufen (!) MyBase.OnValidating(e) End Sub #End Region Der komplette Code der Klasse Nachfolgend der komplette Quellcode der neuen Klasse mit allen eingangs erfüllten Anforderungen. Public Class NumValueInput ' Name der neuen Klasse ' erben von System.Windows.Forms.TextBox Inherits System.Windows.Forms.TextBox Eigenschaften #Region " Propertys " Private varCheckTemp As Boolean ' wird intern benötigt Private varValueDecimale As Integer ' Anzahl der Dezimalstellen Private varValueNumValue As Double ' eingegebener Wert als Double Private varValueExact As Boolean ' exakten Wert speichern Ja/Nein Private varValueToolTip As String ' Text für die Tooltips Private varValueErrorColor As System.Drawing.Color ' Farbe bei Falscheingaben Private varValueNegativColor As System.Drawing.Color ' Farbe bei negativen Zahlen Private varValueErrorMsg As String ' Text bei Fehleingaben Private varValueNegativ As Boolean ' negative Zahlen erlaubt Ja/Nein Private varValueMinimum As Double ' Minimalwert für Eingabe Private varValueMaximum As Double ' Maximalwert für Eingabe Private varValueErrMinMaxMsg As String ' Text für Fehleingabe bei Min/Max Private varValueErrNegativMsg As String ' Text für Fehleingabe bei negativ Private varValueErrQuestMsg As String ' Fragetext bei Fehleingaben Private varValueErrMsgTitle As String ' Überschrift für Fehlermeldungen ' Maximal Wert ? Public Property MaximumValue() As Double Get Return varValueMaximum End Get Set(ByVal Value As Double) varValueMaximum = Value End Set End Property ' Minimal Wert ? Public Property MinimumValue() As Double Get Return varValueMinimum End Get Set(ByVal Value As Double) varValueMinimum = Value End Set End Property ' Negative Werte erlaubt ? Public Property NegativValue() As Boolean Get Return varValueNegativ End Get Set(ByVal Value As Boolean) varValueNegativ = Value End Set End Property ' Allgemeine Fehlermeldung z.B.: ' "Auf 0 setzen und weiter ?" Public Property ErrorMsgPart() As String Get Return varValueErrQuestMsg End Get Set(ByVal Value As String) varValueErrQuestMsg = Value End Set End Property ' Fehlermeldung für falsche Werte Public Property ErrorMsg() As String Get Return varValueErrorMsg End Get Set(ByVal Value As String) varValueErrorMsg = Value End Set End Property ' Titel der Fehlermeldungen Public Property ErrorMsgTitle() As String Get Return varValueErrMsgTitle End Get Set(ByVal Value As String) varValueErrMsgTitle = Value End Set End Property ' Fehlermeldung bei nicht erlaubten negativen Zahlen Public Property ErrorNegativMsg() As String Get Return varValueErrNegativMsg End Get Set(ByVal Value As String) varValueErrNegativMsg = Value End Set End Property ' Fehlermeldung bei Nichteinhalten von Min/Max Public Property ErrorMinMaxMsg() As String Get Return varValueErrMinMaxMsg End Get Set(ByVal Value As String) varValueErrMinMaxMsg = Value End Set End Property ' Farbe für negative Zahlen Public Property NegativColor() As System.Drawing.Color Get Return varValueNegativColor End Get Set(ByVal Value As System.Drawing.Color) varValueNegativColor = Value End Set End Property ' Farbe bei fehlerhaften Eingaben Public Property ErrorColor() As System.Drawing.Color Get Return varValueErrorColor End Get Set(ByVal Value As System.Drawing.Color) varValueErrorColor = Value End Set End Property ' Anzahl der Dezimalstellen Public Property Decimale() As Integer Get Return varValueDecimale End Get Set(ByVal Value As Integer) varValueDecimale = Value End Set End Property ' ToolTipText Public Property ToolTip() As String Get Return varValueToolTip End Get Set(ByVal Value As String) varValueToolTip = Value End Set End Property ' Numerischer Wert (Typ ist Double) von TextBox.Text ' in dieser Eigenschaft steht der Wert als Double direkt ' zu Ihrer Verfügung, z.B. um damit direkt zu rechnen ' ohne vorher diesen konvertieren zu müssen Public Property NumValue() As Double Get Return varValueNumValue End Get Set(ByVal Value As Double) varValueNumValue = Value End Set End Property ' Sollen die mit auf Decimale gerundeten Werten ' oder die kompletten Eingabewerte in <NumValue> gespeichert ' werden (zur weiteren Nutzung bei Berechnungen / ' und die gerundeten (Decimale) werden nur angezeigt ' Achtung !! Es ist nur eine Formatierungs-Rundung ' KEINE mathematische Rundung!!! Public Property CalculateExact() As Boolean Get Return varValueExact End Get Set(ByVal Value As Boolean) varValueExact = Value End Set End Property #End Region Standard-Vorgaben (Default-Werte) #Region " Vom Windows Form Designer generierter Code " Public Sub New() MyBase.New() ' Dieser Aufruf ist für den Windows Form-Designer erforderlich. InitializeComponent() ' Initialisierungen nach dem Aufruf InitializeComponent() hinzufügen Me.varValueErrorColor = System.Drawing.Color.Red Me.varValueNegativColor = System.Drawing.Color.Red Me.varValueNumValue = 0 Me.Text = "0" Me.TextAlign = Windows.Forms.HorizontalAlignment.Right Me.CalculateExact = True Me.varValueErrorMsg = "Input only numeric value!" Me.varValueNegativ = True Me.varValueToolTip = "Input numeric value" Me.varValueErrMinMaxMsg = "Value is not in allow range !" Me.varValueErrNegativMsg = "Negativ Value is not allow!" Me.varValueErrQuestMsg = "Continue (and set the value to 0)? " Me.varValueErrMsgTitle = "Input-Error" End Sub ' UserControl1 überschreibt den Löschvorgang zur Bereinigung der ' Komponentenliste. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub ' Für Windows Form-Designer erforderlich Private components As System.ComponentModel.IContainer ' HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer ' erforderlich ' Sie kann mit dem Windows Form-Designer modifiziert werden. ' Verwenden Sie nicht den Code-Editor zur Bearbeitung. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Methoden #Region " My Code " Public Function CheckValue() As Boolean ' **************************************************** ' * Teste ob es eine numerische Eingabe ist ' * - < Min-Property ' * - > Max-Property ' * ' * RETURN Boolean: ' * True: Eingabe ist OK ' * False: keine Numerische Eingabe oder die Vorgabe ' * für negative zahlen oder die Vorgabe für ' * Min/Max- wird nicht eingehalten Dim lResume As Boolean Dim lNeg As Boolean lNeg = False Me.varCheckTemp = False If IsNumeric(Me.Text) Then If Not Me.NegativValue Then If System.Math.Sign(CDbl(Me.Text)) = -1 Then lNeg = True lResume = False Else lResume = True End If Else lResume = True End If Else lResume = False End If If lResume Then If Me.CalculateExact Then Me.NumValue = CDbl(Me.Text) End If Me.Text = Format(CDbl(Me.Text.Trim), Me.BuildFormatString()) If Not Me.CalculateExact Then Me.NumValue = CDbl(Me.Text) End If If System.Math.Sign(CDbl(Me.Text)) = -1 Then Me.ForeColor = varValueNegativColor Else Me.ForeColor = Me.DefaultForeColor End If CheckValue = True Else If MsgBox(IIf(lNeg, Me.ErrorNegativMsg, Me.ErrorMsg) & _ Chr(10) & Chr(13) & _ Me.ErrorMsgPart, MsgBoxStyle.YesNo + _ MsgBoxStyle.Exclamation, _ Me.ErrorMsgTitle) = MsgBoxResult.Yes Then Me.Text = "0" Me.NumValue = CDbl(Me.Text) Me.Text = Format(CDbl(Me.Text), Me.BuildFormatString()) Me.ForeColor = varValueErrorColor Me.varCheckTemp = True CheckValue = True Else Me.ForeColor = varValueErrorColor CheckValue = False End If End If End Function Private Function BuildFormatString() As String ' Bildet den Format-String für die Anzeige Dim sTemp As String Dim iLauf As Integer sTemp = "" If Me.Decimale > 0 Then sTemp = "." For iLauf = 0 To Me.Decimale - 1 sTemp = sTemp + "0" Next Else sTemp = " " End If sTemp = sTemp + " " BuildFormatString = "##,##0" & sTemp End Function Protected Overrides Sub OnValidating( _ ByVal e As System.ComponentModel.CancelEventArgs) ' Ruft Check-Methode Dim lResume As Boolean lResume = Me.CheckValue If lResume Then If Me.MinimumValue <> Me.MaximumValue Then If (Me.NumValue > Me.MaximumValue) Or _ (Me.NumValue < Me.MinimumValue) Then If Me.varCheckTemp Then Me.Text = Me.MinimumValue Me.NumValue = Me.MinimumValue Else MsgBox(Me.ErrorMinMaxMsg, MsgBoxStyle.Critical + _ MsgBoxStyle.OKOnly, Me.ErrorMsgTitle) lResume = False End If End If End If End If e.Cancel = Not lResume Me.Refresh() MyBase.OnValidating(e) End Sub Protected Overrides Sub OnKeyPress( _ ByVal e As Windows.Forms.KeyPressEventArgs) ' bei "?" zeige die Info-Box ' bei "=" wird CALC.EXE aufgerufen ' bei {ENTER} wird der Cursor weitergesetzt Dim notepadID As Integer Select Case e.KeyChar Case "?" Me.Info() Case Chr(13) Windows.Forms.SendKeys.Send("{TAB}") Case "=" notepadID = Shell("CALC.EXE", AppWinStyle.NormalFocus) ' Neue Instanz von Notepad aktivieren AppActivate(notepadID) End Select MyBase.OnKeyPress(e) End Sub Public Sub Info() MsgBox("TextBox-Class for numeric inputs only." & _ ControlChars.NewLine & _ "This Inputbox accept only numeric Values." & _ ControlChars.NewLine & _ ControlChars.NewLine & _ "(c) by F.Pacher", _ MsgBoxStyle.Information + MsgBoxStyle.OKOnly, "Info") End Sub #End Region End Class ' Abschließen der Klassendefinition Erstellen der DLL und Verwenden in VB.NET Um die neue "NumValueInput"-Komponente nun in eigenen VB.NET Anwendungen nutzen zu können, muss diese als DLL kompiliert werden. Wählen Sie hierzu den Befehl NumValueInputLib erstellen im Menü Erstellen. Die DLL selbst finden Sie jetzt im Unterverzeichnis Bin des Projekt-Ordners. Registrieren der Komponente
Im darauf erscheinenden Dialog aktivieren Sie die Registerkarte .NET Framework Komponenten, klicken auf die Schaltfläche Durchsuchen und doppelklicken auf den Eintrag NumValueInputLib.dll im Bin-Verzeichnis des Projektordners der NumValueInput-Klasse.
Schließen Sie den Dialog Toolbox anpassen, indem Sie auf OK klicken (Achten Sie darauf, dass das Häckchen der NumValueInputLib.dll aktiviert ist). Verwenden der Komponente
Dieser Workshop wurde bereits 41.875 mal aufgerufen.
Anzeige
![]() ![]() ![]() (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevZIP40 Pro DLL ![]() Zippen und Unzippen wie die Profis! Mit nur wenigen Zeilen Code statten Sie Ihre Anwendungen ab sofort mit schnellen Zip- und Unzip-Funktionen aus. Hierbei lassen sich entweder einzelnen Dateien oder auch gesamte Ordner zippen bzw. entpacken. Tipp des Monats ![]() Manfred Bohn IndexOf für mehrdimensionale Arrays Die generische Funktion "IndexOf" ermittelt das erste Auftreten eines bestimmten Wertes in einem n-dimensionalen Array Access-Tools Vol.1 ![]() Über 400 MByte Inhalt Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB |
|||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |