VB.NET Button Click auslösen

VB.NET Button Click auslösen

VB.NET Button Click auslösen

In diesem Beitrag erkläre ich Dir, wie Du in VB.NET ein Button Click auslösen kannst – und zwar via Code!

Falls Du noch gar nicht mit dem Button-Steuerelement gearbeitet hast, kannst Du Dir unter folgendem Link meinen allgemeinen Beitrag zum Button Beispiel anschauen.

Wie Du in VB.NET einen Button zur Laufzeit erstellst, kannst Du in diesem Beitrag hier lernen.

Wir waren alle schonmal da

Ich glaube jeder .NET Entwickler kam zu Beginn seiner Entwickler-Karriere irgendwann an diesen Punkt.

Man hat etwas Tolles in seinen Button gecoded und es lief rund und ohne Fehler.

Nun kommt der Punkt, an dem man diese Funktionalität – versteckter Tipp löl – nun von anderer Stelle aus aufrufen möchte.

Kreative Spielereien

Im Laufe meiner Tätigkeit als Softwareentwickler im Bereich von VB.NET habe ich schon so Einiges gesehen.

Ein lustiges Beispiel war ein völliger VB.NET-Anfänger – daher seid in Gedanken nicht zu hart zu Ihm –, Welcher per codeorientierter Mausbewegung, etc. einen Button anklicken wollte 😂.

Zum Glück muss man nicht auf solche wirklich komplizierte Methoden zurückgreifen, wo kämen wir denn da hin!

Sei gewarnt

Ich möchte an dieser Stelle schonmal direkt den Spoiler erwähnen, dass das, was Du vorhast, nicht das Gelbe vom Ei ist!

Stop Schild – Sei gewarnt
Sei gewarnt

Schreib Dich nicht ab, lern‘..

Ebenfalls möchte ich Dir hier aber keinen Vorwurf machen, denn Du wusstest es vermutlich einfach nicht besser, als Du danach gesucht hast.

Ich selbst kenne diese Problematik aus meiner Anfangszeit als .NET-Entwickler!

Selbstverständlich bin ich froh, dass Dich Deine Suche auf meine Seite und somit zu mir geführt hat 😊.

Meine Erfahrung – häufige Billligung

Umso lustiger wird es – zumeist – nachher, wie man den Wald vor lauter Bäumen nicht sehen konnte.

Manchmal ist es leider jedoch nicht unbedingt so lustig, vor allem, wenn gewisse Aktionen Folgen in: Wartung, Verständnis und mehr nach sich ziehen.

Leider“ musste ich schon oft die Erfahrung machen, dass ehemalige Nachhilfe-Schüler, Internetforen-Nutzer, jedoch auch Kunden, etc. bewusst den falschen Weg wählten.

Oft hieß es: „Ja, ich weiß, dass das so nicht gut ist, aber das ist jetzt einfacher so!“

Code – VB.NET Button Click auslösen

Vorwort

Um das Beispiel nicht zu verkomplizieren habe ich auf tiefgehendere Sachen wie die z. B. die Dependency-Injection verzichtet.

Das Beispiel dürfte ohnehin Aufgrund der zusätzlichen Klassen für Anfänger schon etwas schwieriger sein.

Insgesamt hängt das natürlich vom individuellen Fortschritt in VB.NET und dem Verständnis dafür ab.

Manueller Aufruf der Handler-Sub – Erster Anlauf

Der erste deinerseits versuchte Anlauf könnte ungefähr wie folgt, ausgesehen haben, bzw. aussehen.

Du versuchst die Dir bekannte Sub des Button-Click Ereignishandlers einfach händisch, also via Code aufzurufen.

btnSearchBills_Click()

Doch während Du die Zeile fast fertig tippst, fällt Dir vermutlich auf, dass da was fehlt 🙈.

Die Sub, die Du aufrufen wolltest, erwartet nämlich zwei Parameter, Welche Dich eventuell vor die Frage stellen: „Wo bekomme ich Diese her?“.

sender As Object, e As EventArgs

In der Theorie ist die „Lösung“ ganz einfach – zumindest, wenn man weiß wie 😂:

sender As Object

Der „sender“ ist ja letztendlich nichts anderes, als das Objekt, Welches das Ereignis ausgelöst hat, worauf der Ereignishandler dann reagiert.

Da wir ja wissen, dass der Button letztendlich das Ereignis auslösen würde, können wir Diesen ja schonmal übergeben und machen somit Signatur-technisch nichts verkehrt.

e As EventArgs

Der andere fehlende Parameter, also der Zweite, ist da etwas komplizierter, obwohl ich auch schon beim Ersten sagen kann: „Wenn Du schon beim Sender auf die Lösung gekommen bist – Respekt!“

Die EventArgs-Klasse bietet ein „Shared-Readonly-Feld“ namens „Empty“ an.

Wie der Name schon verrät, handelt es sich bei dem dahinterstehenden „Wert“ praktisch um leere EventArgs„, Welche wir dann mitliefern können, falls wir keine Event-Daten an sich benötigen.

btnSearchBills_Click(btnSearchBills, EventArgs.Empty)

PerformClick – Der einfache Ansatz

Im Endeffekt müssen wir es uns gar nicht so kompliziert wie oben machen.

Das Rumschlagen mit Parametern und das manuelle Aufrufen der Ereignishandler-Sub ist nicht notwendig, da der Button von Haus aus eine Möglichkeit bietet.

Die Methode, die wir suchen heißt *Trommelwirbel*: PerformClick:

btnSearchBills.PerformClick()

VB.NET Button Click auslösen – Der Richtige Ansatz

Im letzten und größten Abschnitt des Beitrages, kommen wir zum richtigenAnsatz.

Ich halte die vorherigen Ansätze für einen schlechten Stil, bzw. für falsch, weil Sie meiner Meinung nach falsche Absichten widerspiegeln.

Wenn man möchte, dass ein Button Click via Code ausgelöst wird, dann möchte man nicht wirklich den Button auslösen, sondern den Code, der dahinter steckt!

Benötigte Steuerelemente

DataGridView

In dem DataGridview zeigen wir die für das Beispiel genutzten Testdaten in Form von Rechnungsdaten an.

2 Labels

Um die Textboxen optional mit Informationen zu bestücken

TextBox

Eine Textbox für die Suche nach einer Rechnung via Id.

TextBox

Dann noch eine weitere Textbox für die Suche nach Rechnungen via Kunden-Name.

Button

Einen Button für den Reset der Suchfelder

Button

Die Suchfunktion auszulösen wird von diesem Button gesteuert.

Eigenschaften

billService

Der Rechnungsservice ist – wie für Services bei Dependency Injection üblich, aber in diesem Fall nicht verwendet – eine „Private Property“.

Bills

Bei „billshandelt es sich um die Rechnungsdaten, die wir für dieses Beispiel testweise erstellen, laden und anzeigen werden.

Konstruktoren

New

Wir brauchen in unserem Fall nur den Standard-Konstruktor, Welchen wir für die Vorbereitung unseres Services und z. B. dem DataGridView nutzen.

Sub New()
    InitializeComponent()
    ' should be done with dependency injection like things
    ' just for displaying puporses..
    billService = New BillService()
    Bills = New List(Of Bill)
    ConfigureBillDataGrid()
End Sub

Methoden

ConfigureBillDataGrid

Ich denke diese Methode ist relativ selbsterklärend.

Private Sub ConfigureBillDataGrid()
    With dgvBills
        .AllowUserToAddRows = False
        .AllowUserToDeleteRows = False
        .AllowUserToResizeRows = False
        .AllowUserToOrderColumns = False
        .AllowUserToResizeColumns = False
        .ReadOnly = True
        .SelectionMode = DataGridViewSelectionMode.FullRowSelect
        .BackgroundColor = Color.White
        .RowHeadersVisible = False
        ' columns being added in visual designer..
    End With
End Sub
btnSearchBills_Click

Das ist die Click-Ereignishandler-Sub für den Button.

Private Sub btnSearchBills_Click(sender As Object, e As EventArgs) Handles btnSearchBills.Click
    SearchBills()
End Sub
SearchBills

Das ist der Star des Tages, denn diese Sub ist die letztendliche Alternative zum „Button.PerformClick()“.

ShowBillsInDataGrid

Hier kommt der Code rein, der notwendig ist, um die Rechnungen anzuzeigen.

Private Sub ShowBillsInDataGrid(bills As List(Of Bill))
    ' could/should be done with BindingList which supports AddRange
    ' but thats part of another tutorial :)
    ' so this is it for now
    dgvBills.DataSource = Nothing
    Me.Bills.Clear()
    Me.Bills.AddRange(bills)
    dgvBills.DataSource = Me.Bills
End Sub
btnClearSearchFields_Click

Das ist der Ereignishandler für das Klick-Ereignis des Reset-Buttons für die Suchfelder.

Private Sub btnClearSearchFields_Click(sender As Object, e As EventArgs) Handles btnClearSearchFields.Click
    tbBillId.Clear()
    tbBillCustomer.Clear()
    ' or
    ' tbBillCustomer.Text = ""
End Sub
SearchBox_KeyDown

Das ist die Methode, die auf die KeyDown-Ereignisse der 2 Suchfelder reagiert.

Wenn in einem der Suchfelder die Escape-Taste gedrückt wird, nehmen wir das als Befehl dafür, dass die Felder zurückgesetzt werden sollen.

Bei der Verwendung der Enter-Taste, lösen wir die Suche der Rechnungen erneut aus.

Private Sub SearchBox_KeyDown(sender As Object, e As KeyEventArgs) Handles tbBillId.KeyDown, tbBillCustomer.KeyDown
    If e.KeyCode = Keys.Escape Then
       Dim theTextBox = CType(sender, TextBox)
       theTextBox.Clear()
    ElseIf e.KeyCode = Keys.Enter Then
        SearchBills()
    End If
End Sub

Bill-Klasse

Diese Klasse spiegelt eine einzelne Rechnung wieder.

Die Id ist denke ich selbstredend..

Der Customer wurde hier bewusst als String, statt als Objekt gewählt, um das Beispiel einfacher zu halten und den Fokus nicht zu verschieben.

Public Class Bill

    Public Property Id As Integer

    ' should be an object but for this example, made easier
    Public Property Customer As String

    Sub New()

    End Sub

    Sub New(id As Integer)
        Me.Id = id
    End Sub

    Sub New(id As Integer, customer As String)
        Me.Id = id
        Me.Customer = customer
    End Sub

End Class

BillService-Klasse

Diese Klasse spiegelt einen Service für die Aktionen bezüglich der Rechnungen wieder.

Wenn eine neue Instanz der BillService-Klasse erzeugt wird, lade ich im Konstruktor deren Testdaten, ansonsten würden Diese natürlich aus einer Datenbank o. Ä. kommen.

Sie bietet eine Funktion an, um eine Rechnung via Id zu suchen.

Zusätzlich gibt es eine Funktion, um Rechnungen anhand des Kundennamens zu finden.

Um die Parameter dynamisch zu halten, habe ich ein Dictionary verwendet.

Wenn in Diesem ein Schlüssel namens customer“ drin ist, wird der dahinter stehende Wert als Such-Name verwendet – Großschreibung nicht beachtend.

Public Class BillService

    Private bills As List(Of Bill)

    Sub New()
        bills = New List(Of Bill)
        MockupData()
    End Sub

    Private Sub MockupData()
        With bills
            .Add(New Bill(1, "John Doe"))
            .Add(New Bill(2, "Jane Doe"))
            .Add(New Bill(3, "Maximilian Maximum"))
            .Add(New Bill(4, "Jesus Christ"))
            .Add(New Bill(5, "Michael Jackson"))
        End With
    End Sub

    Public Function FindById(id As Integer) As Bill
        Return bills.SingleOrDefault(Function(x) x.Id = id)
        '' or the selfmade long version:
        'For Each bill In bills
        '    If bill.Id = id Then
        '        Return bill
        '    End If
        'Next
        'Return Nothing
    End Function

    Public Function FindAllBy(criteria As Dictionary(Of String, String)) As List(Of Bill)
        Dim filteredBills = New List(Of Bill)
        ' first put all in
        filteredBills.AddRange(bills)
        ' filter for example by name 
        If criteria.ContainsKey("customer") Then
            Dim customer = criteria.Item("customer").ToLower()
            filteredBills = filteredBills.Where(Function(x) x.Customer.ToLower().Contains(customer)).ToList()
        End If
        ' add more filtering..
        Return filteredBills
    End Function

End Class

Der komplette Code – VB.NET Button Click auslösen

In diesem Abschnitt findest du den kompletten Code zum Thema: VB.NET Button Click auslösen.

Public Class Form1

    Private Property billService As BillService

    Public Property Bills As List(Of Bill)

    Sub New()
        InitializeComponent()
        ' should be done with dependency injection like things
        ' just for displaying puporses..
        billService = New BillService()
        Bills = New List(Of Bill)
        ConfigureBillDataGrid()
    End Sub

    Private Sub ConfigureBillDataGrid()
        With dgvBills
            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToResizeRows = False
            .AllowUserToOrderColumns = False
            .AllowUserToResizeColumns = False
            .ReadOnly = True
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .BackgroundColor = Color.White
            .RowHeadersVisible = False
            ' columns being added in visual designer..
        End With
    End Sub

    Private Sub btnSearchBills_Click(sender As Object, e As EventArgs) Handles btnSearchBills.Click
        SearchBills()
    End Sub

    Private Sub SearchBills()
        Dim givenIdText = tbBillId.Text.Trim()
        Dim billId As Integer
        Dim bills As List(Of Bill) = New List(Of Bill)
        If Integer.TryParse(givenIdText, billId) Then
            Dim bill = billService.FindById(billId)
            If bill IsNot Nothing Then
                bills.Add(bill)
            End If
            ShowBillsInDataGrid(bills)
            ' OpenDetailForm() – Maybe?
            Return
        End If

        Dim searchCriteria = New Dictionary(Of String, String)

        Dim customerName = tbBillCustomer.Text.Trim()
        If Not String.IsNullOrWhiteSpace(customerName) Then
            searchCriteria.Add("customer", customerName)
        End If

        Dim searchResults = billService.FindAllBy(searchCriteria)
        bills.AddRange(searchResults)
        ShowBillsInDataGrid(bills)
    End Sub

    Private Sub ShowBillsInDataGrid(bills As List(Of Bill))
        ' could/should be done with BindingList which supports AddRange
        ' but thats part of another tutorial :)
        ' so this is it for now
        dgvBills.DataSource = Nothing
        Me.Bills.Clear()
        Me.Bills.AddRange(bills)
        dgvBills.DataSource = Me.Bills
    End Sub

    Private Sub btnClearSearchFields_Click(sender As Object, e As EventArgs) Handles btnClearSearchFields.Click
        tbBillId.Clear()
        tbBillCustomer.Clear()
        ' or
        ' tbBillCustomer.Text = ""
    End Sub

    Private Sub SearchBox_KeyDown(sender As Object, e As KeyEventArgs) Handles tbBillId.KeyDown, tbBillCustomer.KeyDown
        If e.KeyCode = Keys.Escape Then
            Dim theTextBox = CType(sender, TextBox)
            theTextBox.Clear()
        ElseIf e.KeyCode = Keys.Enter Then
            SearchBills()
        End If
    End Sub

End Class

Public Class Bill

    Public Property Id As Integer

    ' should be an object but for this example, made easier
    Public Property Customer As String

    Sub New()

    End Sub

    Sub New(id As Integer)
        Me.Id = id
    End Sub

    Sub New(id As Integer, customer As String)
        Me.Id = id
        Me.Customer = customer
    End Sub

End Class

Public Class BillService

    Private bills As List(Of Bill)

    Sub New()
        bills = New List(Of Bill)
        MockupData()
    End Sub

    Private Sub MockupData()
        With bills
            .Add(New Bill(1, "John Doe"))
            .Add(New Bill(2, "Jane Doe"))
            .Add(New Bill(3, "Maximilian Maximum"))
            .Add(New Bill(4, "Jesus Christ"))
            .Add(New Bill(5, "Michael Jackson"))
        End With
    End Sub

    Public Function FindById(id As Integer) As Bill
        Return bills.SingleOrDefault(Function(x) x.Id = id)
        '' or the selfmade long version:
        'For Each bill In bills
        '    If bill.Id = id Then
        '        Return bill
        '    End If
        'Next
        'Return Nothing
    End Function

    Public Function FindAllBy(criteria As Dictionary(Of String, String)) As List(Of Bill)
        Dim filteredBills = New List(Of Bill)
        ' first put all in
        filteredBills.AddRange(bills)
        ' filter for example by name 
        If criteria.ContainsKey("customer") Then
            Dim customer = criteria.Item("customer").ToLower()
            filteredBills = filteredBills.Where(Function(x) x.Customer.ToLower().Contains(customer)).ToList()
        End If
        ' add more filtering..
        Return filteredBills
    End Function

End Class

Downloads

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.