Event Handler zur Laufzeit aktivieren?

21/07/2009 - 15:35 von Steffen Meyer | Report spam
Hallo zusammen,

ich hab ein Problem, bei dem ich als Anfànger momentan nicht weiter komme:

Ich verwende Visual Basic 2005 und habe ein DataGridView in einem Formular.
Mein Problem dabei ist nun, dass ich bei dem Event DataGridView.RowEnter die
aktuelle Zeile auslesen möchte. Das funktioniert ansich auch, allerdings
wird das Event schon ausgelößt bevor das Formular angezeigt wird und den
Focus erhàlt.

Ich hab mich mit AddHandler usw. versucht, doch leider muss ich dagen, dass
ich nicht kapiere, wie das funktionieren könnte.

Ich fànde es prima, wenn mir jemand einenAnsatz zeigen/erklàren könnte, wie
ich den Handler erst zur Laufzeit aktivieren/erstellen kann.

Besten Dank
Steffen
 

Lesen sie die antworten

#1 Peter Götz
21/07/2009 - 16:17 | Warnen spam
Hallo Steffen,

Ich verwende Visual Basic 2005 und habe ein DataGridView
in einem Formular.



Wie ist das DGV in Dein Formular gekommen?
Durch Deinen eigenen Code oder hast Du das
DGV im Designer einfach auf die Form gezogen?

Mein Problem dabei ist nun, dass ich bei dem
Event DataGridView.RowEnter die aktuelle Zeile
auslesen möchte. Das funktioniert ansich auch,
allerdings wird das Event schon ausgelößt bevor
das Formular angezeigt wird und den Focus erhàlt.



RowEnter wird immer dann ausgelöst, wenn im DGV
eine Zeile zur aktiven Zeile wird, also auch dann, wenn
das DGV frisch geladen wurde, mit Daten verbunden
wurde und dann z.B. die erste Zeile dieser Daten zur
aktuellen Zeilen macht.


Ich hab mich mit AddHandler usw. versucht, doch leider
muss ich dagen, dass ich nicht kapiere, wie das
funktionieren könnte.



Da Du vermutlich Dein DGV nicht per eigenem Code,
sondern via Designer erstellt hast, sind damit alle
Ereignishandler vom Designer schon erstellt worden.
AddHandler kommt in diesem Fall nicht in Frage.


Ich fànde es prima, wenn mir jemand einenAnsatz
zeigen/erklàren könnte, wie ich den Handler erst zur
Laufzeit aktivieren/erstellen kann.



Hier erst mal ein einfaches Beispiel ohne AddHandler,
bei dem einfach mit einer Flag-Variable (mLoaded)
geprüft wird, ob die Form und das darauf befindliche
DGV schon vollstàndig geladen sind. Das ist z.B. dann
der Fall, wenn das Form_Shown-Ereignis ausgelöst
worden ist.

Kopiere den nachfolgenden Code einfach in ein
leeres Formmodul (Form1.vb).

' /// Code in Form1.vb
Public Class Form1
Private WithEvents DGV As DataGridView
Private mDT As DataTable
Private mDV As DataView
Private mLoaded As Boolean

Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns.Add("SText", GetType(String))
.Columns.Add("LText", GetType(String))

For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i, False)
DR.Item(2) = MonthName(i, True)
.Rows.Add(DR)
Next
.AcceptChanges()
End With

mDV = New DataView(mDT)
End Sub

Private Sub Form1_Load _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Load

DGV = New DataGridView
With DGV
.SetBounds _
(10, 10, _
Me.ClientSize.Width - 20, _
Me.ClientSize.Height - 20)

.Anchor = _
AnchorStyles.Left Or _
AnchorStyles.Top Or _
AnchorStyles.Right Or _
AnchorStyles.Bottom

.DefaultCellStyle.Font = _
New Font("Arial", 12)

.ColumnHeadersDefaultCellStyle.Font = _
New Font("Arial", 8, FontStyle.Bold)

End With
Me.Controls.Add(DGV)

CreateData()

DGV.DataSource = mDV
DGV.AutoResizeColumns()
End Sub


Private Sub Form1_Shown _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Shown

mLoaded = True
End Sub

Private Sub DGV_RowEnter _
(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs _
) Handles DGV.RowEnter

If mLoaded Then
If DGV.CurrentRow IsNot Nothing Then
Beep()

Dim strBuffer As String
Dim DRV As DataRowView
DRV = mDV.Item(e.RowIndex)

strBuffer = _
DRV.Item(0).ToString & "; " & _
DRV.Item(1).ToString & "; " & _
DRV.Item(2).ToString

Console.WriteLine(strBuffer)
End If
End If
End Sub
End Class
' \\\ E N T E

Im vorstehenden Beispiel wird das DGV so deklariert:

Private WithEvents DGV As DataGridView

Genauso macht es auch der Designer in dem von ihm
autom. generierten Code. Wenn mit

DGV = New DataGridView

eine neue Instanz eines DataGridView erstellt wird,
sind damit auch alle Ereignishandler, sofern benutzt
scharf.

Nach dem Programmstart wird in Form_Shown wird die
Variable mLoaded auf True gesetzt und erst dann kann
der Code in DGV_RowEnter zur Wirkung kommen.

Stellt sich allerdings die Frage, warum Du das erste
DGV_RowEnter, gleich nach dem Laden des DGV
nicht auswerten willst?


Mit AddHandler würde das so aussehen:

' /// Code in Form1.vb

Public Class Form1
Private DGV As DataGridView
Private mDT As DataTable
Private mDV As DataView

Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow

mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns.Add("SText", GetType(String))
.Columns.Add("LText", GetType(String))

For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i, False)
DR.Item(2) = MonthName(i, True)
.Rows.Add(DR)
Next
.AcceptChanges()
End With

mDV = New DataView(mDT)
End Sub

Private Sub Form1_Load _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Load

DGV = New DataGridView
With DGV
.SetBounds _
(10, 10, _
Me.ClientSize.Width - 20, _
Me.ClientSize.Height - 20)

.Anchor = _
AnchorStyles.Left Or _
AnchorStyles.Top Or _
AnchorStyles.Right Or _
AnchorStyles.Bottom

.DefaultCellStyle.Font = _
New Font("Arial", 12)

.ColumnHeadersDefaultCellStyle.Font = _
New Font("Arial", 8, FontStyle.Bold)

End With
Me.Controls.Add(DGV)

CreateData()

DGV.DataSource = mDV
DGV.AutoResizeColumns()

End Sub


Private Sub Form1_Shown _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Shown

AddHandler DGV.RowEnter, AddressOf DGV_RowEnter
End Sub

Private Sub Form1_FormClosing _
(ByVal sender As Object, _
ByVal e As FormClosingEventArgs _
) Handles Me.FormClosing

RemoveHandler _
DGV.RowEnter, AddressOf DGV_RowEnter

End Sub

Private Sub DGV_RowEnter _
(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs)

If DGV.CurrentRow IsNot Nothing Then
Beep()

Dim strBuffer As String
Dim DRV As DataRowView
DRV = mDV.Item(e.RowIndex)

strBuffer = _
DRV.Item(0).ToString & "; " & _
DRV.Item(1).ToString & "; " & _
DRV.Item(2).ToString

Console.WriteLine(strBuffer)
End If
End Sub
End Class
' \\\ E N T E

Beim zweiten Beispiel ist das DataGridView so deklariert:

Private DGV As DataGridView

Also ohne das WithEvents und nun kannst Du jeden
benötigten Ereignishandler selbst definieren. Im
Beispiel geschieht das wieder in Form_Shown()
mit AddHandler.
In Form_Closing siehst Du, wie man einen solchen
Ereignishandler per RemoveHandler wieder
deaktiviert.

Alles klar?

Mehr Beispiele zum DGV und auch andere findest
Du unter

www.gssg.de -> Visual Basic -> VB.net

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

Ähnliche fragen