vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Controls · Sonstiges   |   VB-Versionen: VB5, VB606.11.05
Zentrale Auswertung der Control-Events

Mit Hilfe eines Klassenmoduls werden die Events bestimmter oder aller Controls eines Formulars gekapselt und zentral ausgelöst.

Autor:   Roland OrtegaBewertung:     [ Jetzt bewerten ]Views:  19.847 
ohne HomepageSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Oft kommt es vor, dass man an einer zentralen Stelle auf die Ereignisse von verschiedenen Controls reagieren möchte. Beispielsweise habe ich mir angewöhnt, alle Interaktionen innerhalb eines Formulars in einer zentralen Prozedur zu sammeln. Je nach Listbox / Checkbox / Textbox Auswahl werden weitere Controls sichtbar / unsichtbar bzw enabled oder disabled.

Solange man nur mit Steuerelement-Feldern arbeitet ist das in VB ja gar kein Thema. Was ist aber, wenn man etliche unterschiedliche Textboxen hat. Immer wenn sich eine ändert, soll das ganze Formular zentral überprüft werden. Dann muss man für jede Textbox das Event "Change" programmieren. Das ist viel stupider Code.

Nachfolgend möchten wir Ihnen eine einfache Lösung mit Hilfe von Klassen vorstellen, in der man mit nur einer Event-Prozedur über etliche Events verschiedener Controls informiert wird.

Erstellen Sie ein neues Projekt und fügen ein neues Klassenmodul mit dem Namen "clsControlHandler" hinzu. Fügen Sie nachfolgenden Code in das Klassenmodul ein:

Option Explicit
 
' zusätzliche Control-Infos
Private Type tpObjDaten
  Parent As clsMultiControlEvent
  InitOK As Boolean
End Type
 
Private m As tpObjDaten
 
' Hier alle Control-Objekte deklarieren, auf deren
' Ereignisse Sie zentral reagieren möchten
Private WithEvents cTextbox As VB.TextBox
Private WithEvents cListBox As VB.ListBox
Private WithEvents cCommand As VB.CommandButton
Private WithEvents cCheckBox As VB.CheckBox
Private WithEvents cOptionButton As VB.OptionButton
' Initialisierung
Public Sub Init(ByVal refCon As Object, Parent As clsMultiControlEvent)
  Set m.Parent = Parent
 
  m.InitOK = False
 
  ' keine Steuerelementfelder!
  Dim Index As Integer
  On Error Resume Next
  Index = refCon.Index
  If Err.Number <> 0 Then
    ' Objekt-Typ abfragen
    Select Case TypeName(refCon)
      Case "TextBox"
        Set cTextbox = refCon
        m.InitOK = True
 
      Case "ListBox"
        Set cListBox = refCon
        m.InitOK = True
 
      Case "CommandButton"
        Set cCommand = refCon
        m.InitOK = True
 
      Case "CheckBox"
        Set cCheckBox = refCon
        m.InitOK = True
 
      Case "OptionButton"
        Set cOptionButton = refCon
        m.InitOK = True
 
    End Select
  End If
End Sub
' Rückgabe, ob Initialisierung erfolgreich war
Public Property Get InitOK() As Boolean
  InitOK = m.InitOK
End Property
' Referenz-Objkekte zerstören
Public Sub Terminate()
  Set cTextbox = Nothing
  Set cListBox = Nothing
  Set cCommand = Nothing
  Set cCheckBox = Nothing
  Set cOptionButton = Nothing
 
  Set m.Parent = Nothing
End Sub
' Klick-Event der CheckBox weiterleiten
Private Sub cCheckbox_Click()
  m.Parent.Click cCheckBox
End Sub
 
' GotFocus-Event der CheckBox weiterleiten
Private Sub cCheckbox_GotFocus()
  m.Parent.GotFocus cCheckBox
End Sub
' Klick-Event des CommandButton weiterleiten
Private Sub cCommand_CLick()
  m.Parent.Click cCommand
End Sub
 
' GotFocus-Event des CommandButton weiterleiten
Private Sub cCommand_GotFocus()
  m.Parent.GotFocus cCommand
End Sub
' Klick-Event des OptionButton weiterleiten
Private Sub cOptionButton_Click()
  m.Parent.Click cOptionButton
End Sub
 
' GotFocus-Event des OptionButton weiterleiten
Private Sub cOptionButton_GotFocus()
  m.Parent.GotFocus cOptionButton
End Sub
' Change-Event der TextBox weiterleiten
Private Sub cTextbox_Change()
  m.Parent.Change cTextbox
End Sub
 
' Click-Event der TextBox weiterleiten
Private Sub cTextbox_Click()
  m.Parent.Click cTextbox
End Sub
 
' GotFocus-Event der TextBox weiterleiten
Private Sub cTextbox_GotFocus()
  m.Parent.GotFocus cTextbox
End Sub
' Click-Event der ListBox weiterleiten
Private Sub cListBox_Click()
  m.Parent.Click cListBox
End Sub
 
' GotFocus-Event der ListBox weiterleiten
Private Sub cListBox_GotFocus()
  m.Parent.GotFocus cListBox
End Sub

Jetzt benötigen wir noch ein weiteres Klassenmodul mit dem Namen "clsMultiControlEvent" und folgendem Code:

Option Explicit
 
' Ereignisse
Public Enum enEventtyp
  enClick = 1         ' Werte immer verdoppeln!
  enChange = 2
  enGotFocus = 4
  enLostFocus = 8
 
  enAll = 15          ' Summe aus allen vorigen Werten
End Enum
 
Private Type tpObjDaten
  ContrClasses() As clsControlHandler
  Filter As enEventtyp
End Type
 
Private m As tpObjDaten
 
' zentrales Ereignis
Public Event UniEvent(sourcename As String, sourceobj As Object, _
  EventName As String, EventNr As enEventtyp)
Private Sub Class_Initialize()
  ' Initialisieren
  ReDim m.ContrClasses(0)
  m.Filter = enAll
End Sub
' alle referenzierten Control-Objekte zerstören
Public Sub Terminate()
  Dim i As Long
 
  For i = 1 To UBound(m.ContrClasses)
    m.ContrClasses(i).Terminate
  Next i
  ReDim m.ContrClasses(0)
End Sub
Private Sub Class_Terminate()
  ' Klasse zerstören
  Terminate
End Sub
' Ereignis-Filter setzen
Public Sub Filter(OnlyRiseTheseEvents As enEventtyp)
  m.Filter = OnlyRiseTheseEvents
End Sub
' Hinzufügen eines einzelnen ControlsA
Public Sub Add(refCon As Control)
  Dim nCount As Long
 
  nCount = UBound(m.ContrClasses) + 1
  ReDim Preserve m.ContrClasses(nCount)
  Set m.ContrClasses(nCount) = New clsControlHandler
  m.ContrClasses(nCount).Init refCon, Me
 
  If Not m.ContrClasses(nCount).InitOK Then
    m.ContrClasses(nCount).Terminate
    ReDim Preserve m.ContrClasses(nCount - 1)
  End If
End Sub
' mehrere Controls auf einmal hinzufügen
Public Sub AddMulti(ParamArray refControls() As Variant)
  Dim i As Long
  Dim nCount As Long
 
  nCount = UBound(refControls)
  ReDim m.ContrClasses(nCount + 1)
 
  For i = 0 To UBound(refControls)
    Set m.ContrClasses(i + 1) = New clsControlHandler
    m.ContrClasses(i + 1).Init refControls(i), Me
  Next i
End Sub
' Alle Controls der übergebenen Form hinzufügen
Public Sub AddFormComplete(refForm As Form)
  Dim oControl As Object
  Dim i As Long
 
  i = 0
  For Each oControl In refForm.Controls
    i = i + 1
    ReDim Preserve m.ContrClasses(i)
    Set m.ContrClasses(i) = New clsControlHandler
    m.ContrClasses(i).Init oControl, Me
    If m.ContrClasses(i).InitOK = False Then
      m.ContrClasses(i).Terminate
      i = i - 1
    End If
  Next
End Sub
' Click-Ereignis zentral auslösen, falls nicht ausgefiltert
Friend Sub Click(sourceobj As Object)
  If (m.Filter And enClick) = 0 Then Exit Sub
  RaiseEvent UniEvent(sourceobj.Name, sourceobj, "Click", enClick)
End Sub
 
' Change-Ereignis zentral auslösen, falls nicht ausgefiltert
Friend Sub Change(sourceobj As Object)
  If (m.Filter And enChange) = 0 Then Exit Sub
  RaiseEvent UniEvent(sourceobj.Name, sourceobj, "Change", enChange)
End Sub
 
' GotFocus-Ereignis zentral auslösen, falls nicht ausgefiltert
Friend Sub GotFocus(sourceobj As Object)
  If (m.Filter And enGotFocus) = 0 Then Exit Sub
  RaiseEvent UniEvent(sourceobj.Name, sourceobj, "GotFocus", enGotFocus)
End Sub

Anwendung der Klassen
Nachfolgend ein kleines Beispiel, das die Anwendung der Klasse verdeutlichen soll.

Platzieren Sie auf die Form1 folgende Controls:

  • TextBox "Text1"
  • TextBox "Text2"
  • ListBox "List1"
  • CommandButton "Command1"
  • CheckBox "Check1"
  • Label "Label1"

Fügen Sie in den Codeteil der Form1 folgenden Code ein:

Option Explicit
 
' Klassenobjekt der zentralen Event-Behandlung
Private WithEvents MultiEvent As clsMultiControlEvent
Private Sub Form_Load()
  ' Klasse instanzieren
  Set MultiEvent = New clsMultiControlEvent
 
  ' Möglichkeit 1: Die Controls einzeln übergeben
  ' MultiEvent.Add Me.Text1
  ' MultiEvent.Add Me.Text2
  ' MultiEvent.Add Me.List1
  ' ...
 
  ' Möglichkeit 2: alle auf einmal.....
  ' MultiEvent.AddMulti Me.Text1, Me.Text2, Me.List1, ...
 
  ' Möglichkeit 3: der ganz heftige Weg...
  MultiEvent.AddFormComplete Me
 
  ' Falls nur auf bestimmte Ereignisse reagiert werden soll  
  ' MultiEvent.Filter enClick    
End Sub
Private Sub MultiEvent_UniEvent(sourcename As String, _
  sourceobj As Object, EventName As String, EventNr As enEventtyp)
 
  ' Contorlname und Ereignis im Label-Control anzeigen
  Me.Label1.Caption = sourcename & " : " & EventName
End Sub
Private Sub Form_Unload(Cancel As Integer)
  ' Klasse zerstören
  Set MultiEvent = Nothing
End Sub

Hauptnutzen dieser Klasse ist für mich die Formularsteuerung.

Beispiel:
Ein kleines Rechenprogramm bestehend aus den Feldern: Beitrag, Laufzeit, Zinssatz, Anfangskapital und Dynamik weist am Ende das Guthaben aus. Natürlich soll nach Änderung eines beliebigen Wertes die Endsumme neu berechnet werden. Und da gibt es eben die Möglichkeit Steuerelementefeld (=> schlecht lesbarer Code) oder eben für jedes Feld die Click/Change Eventprozedur.
 

Dieser Tipp wurde bereits 19.847 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (1 Beitrag)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(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.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
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.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel