Hallo Hartmut,
Post by Hartmut CalliesAn die typischen ComboBox-Eigenschaften wie z.B.
SelectedIndex von einer ComboBox im DataGridView
gelange ich nur durch die Typ-Konvertierung mit
cboGrid = DirectCast(e.Control, ComboBox)
Ja, zwangsläufig, weil DataGridView.EditingControl
ja nicht nur eine ComboBox, sondern z.B. ja auch
eine Textbox oder irgendein anderer ControlTyp
sein könnte.
Post by Hartmut CalliesAusgangspunkt dafür ist aber, dass ich die ComboBox
im DataGridView z.B. per Klick auswählt habe.
Ja, zumindest einmal muss das .EditingControl sichtbar
geworden sein, um eine entspr. Zuordnung machen zu
können.
Post by Hartmut CalliesWie kann ich aber eine ComboBox im DataGridView
zu einer "Standard"-ComboBox konvertieren, wenn ich
diese nicht per Klick ausgewählt habe, um z.B. an die
Eigenschaft SelectedIndex zu gelangen?
Mindestens einmal musst Du in _EditingControlShowing
einer Objektvariablen, die Du z.B. mit WithEvents
deklariert hast einen Verweis aus e.Control übergeben
und ab dann bekommst Du über diese Ojektvariable
alle Ereignisse der ComboBox mit und hast darüber
auch Zugriff auf alle Eigenschaften der ComboBox.
Das Problem dabei ist nur, dass ComboBox.SelectedItem
ständig wechselt, je nachdem welchen Datensatz Du
auswählst, bzw. abhängig davon, ob die ComboBox
sichtbar gemacht wird oder nicht.
... schnipp...
Post by Hartmut CalliesTrotzdem würde es mich interessieren, wie ich die
SelectedIndex-Eigenschaft von einer nicht ausgewählten
(Klick) ComboBox (DisplayStyle = Nothing) erhalte, um
auch hier den Index von der ComboBox in Spalte 0
gleich dem Index von der ComboBox von Spalte 1
zu setzen.
Hast Du auch dafür eine Lösung?
Das Problem dabei ist, dass sich ComboBox.SelectedItem
nicht unbedingt beim Wechsel zu einem neuen Datensatz
ändert, sondern erst dann, wenn die ComboBox wirklich
durch Anklicken der jeweiligen Grid-Zelle geöffnet wird.
Das nachfolgende Beispiel zeigt, in welchen Situationen
sich ComboBox.SelectedItem ändert.
Public Class Form1
Private WithEvents DGV As DataGridView
Private mDT As DataTable
Private mDV As DataView
Private mDTcbo As DataTable
Private mDVcbo As DataView
Private WithEvents mCM As CurrencyManager
Private WithEvents mCBox As ComboBox
Private Sub Form1_Load _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles Me.Load
CreateData()
InitDGV()
DGV.DataSource = mDV
DGV.AutoResizeColumns()
End Sub
Private Sub InitDGV()
Dim dgvTBCol As DataGridViewTextBoxColumn
Dim dgvCBCol As DataGridViewComboBoxColumn
Dim i As Integer
DGV = New DataGridView
With DGV
.Dock = DockStyle.Fill
.AutoGenerateColumns = False
For i = 0 To 1
dgvTBCol = New DataGridViewTextBoxColumn
With dgvTBCol
.Name = mDT.Columns(i).ColumnName
.HeaderText = .Name
.DataPropertyName = .Name
.ValueType = mDT.Columns(i).DataType
End With
.Columns.Add(dgvTBCol)
Next i
dgvCBCol = New DataGridViewComboBoxColumn
With dgvCBCol
.Name = mDT.Columns(2).ColumnName
.HeaderText = .Name
.DataPropertyName = .Name
.DataSource = mDVcbo
.DisplayMember = mDTcbo.Columns(1).ColumnName
'.ValueMember = mdtb
End With
.Columns.Add(dgvCBCol)
.DefaultCellStyle.Font = New Font("Arial", 12)
.ColumnHeadersDefaultCellStyle.Font = _
New Font("Arial", 8, FontStyle.Bold)
End With
Me.Controls.Add(DGV)
End Sub
Private Sub CreateData()
Dim i As Integer
Dim DR As DataRow
mDTcbo = New DataTable
With mDTcbo
.Columns.Add("ID", GetType(Integer))
.Columns.Add("Monat", GetType(String))
For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i)
.Rows.Add(DR)
Next
.AcceptChanges()
End With
mDVcbo = New DataView(mDTcbo)
mDT = New DataTable
With mDT
.Columns.Add("ID", GetType(Integer))
.Columns.Add("Mon", GetType(String))
.Columns.Add("Monat", GetType(String))
For i = 1 To 12
DR = .NewRow
DR.Item(0) = i
DR.Item(1) = MonthName(i, True)
DR.Item(2) = MonthName(i, False)
.Rows.Add(DR)
Next
.AcceptChanges()
End With
mDV = New DataView(mDT)
mCM = DirectCast(Me.BindingContext(mDV), CurrencyManager)
End Sub
Private Sub DGV_EditingControlShowing _
(ByVal sender As Object, _
ByVal e As DataGridViewEditingControlShowingEventArgs _
) Handles DGV.EditingControlShowing
' Hier wird einmalig der Objektverweis auf die
' ComboBox geholt und bleibt dann bestehen.
If mCBox Is Nothing Then
If DGV.CurrentCellAddress.X = 2 Then
mCBox = DirectCast(e.Control, ComboBox)
End If
End If
End Sub
Private Sub mCM_PositionChanged _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles mCM.PositionChanged
If mCBox IsNot Nothing Then
Console.WriteLine _
("mCM_PositionChanged mCBox.SelectedIndex: " _
& mCBox.SelectedIndex.ToString)
End If
End Sub
Private Sub mCBox_SelectedIndexChanged _
(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles mCBox.SelectedIndexChanged
Console.WriteLine _
("mCBox_SelectedIndexChanged mCBox.SelectedIndex: " _
& mCBox.SelectedIndex.ToString)
End Sub
End Class
Nach dem Programmstart muss einmal die ComboBox
in irgendeiner Zelle geöffnet werden um für die Variable
mCBox einen Verweis auf das .EditingControl (ComboBox)
zu erhalten. Im Ausgabefenster siehst Du dann bei
Datensatzwechseln bzw. beim Öffnen der ComboBox in
verschiedenen Zellen, wie sich mCBox.SelectedIndex
ändert.
Beim Abfragen von mCBox.SelectedItem musst Du Dir
also immer erst mal überlegen, ob dies der Zustand ist
wie er in einer vorher aktiven Zelle war oder ob es der
Zustand in der gerade aktiven Zelle ist.
Das Problem ist halt einfach, dass es ja nur eine einzige
ComboBox für alle Zellen Deiner DataGridComboBoxColumn
gibt und deren SelectedIndex-Eigenschaft sich halt ständig,
je nach Benutzeraktion ändert.
Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)