none
DataGridView-ComboBoxColumn RRS feed

  • Frage

  • Hallo Leute,
    wenn ich bei einem DGV eine neue Zeile hinzufügen möchte, dann brauche ich bei einer TextBoxColumn nur in die unterste Zeile (New Row) einen Text eingeben und die neue Zeile wird automatisch angelegt.
    Genauso funktioniert es, wenn ich eine Auswahl in einer Combobox in einer ComboBoxColumn mit ComboBoxStyle = Dropdown mache.

    Verwende ich jedoch ComboBoxStyle = DropDownList, dann wird nach Auswahl eines Elements in der Auflistung keine neue Zeile angelegt.

    Warum ist das so, bzw. was kann ich dagegen machen?

    Vielen Dank im Voraus


    Christian Tauschek

    Donnerstag, 1. November 2018 09:15

Antworten

  • Hi Christian,
    etwas unklar ist, was Du machst. Die DataGridViewComboBoxColumn hat nur 3 Style-Einstellungen:

    ComboBox
    DropDownButton
    Nothing

    Wie Du ComboBoxStyle = DropDownList einstellst, ist unklar.

    Weiterhin ist zu beachten, dass die neue Zeile (unten) nur ein Platzhalter ist. Erst mit der Änderung in einer Zelle (Spalte) wird ein NewRow ausgeführt und die neue Zeile der Datenquelle hinzugefügt.

    Hier mal eine Demo, mit der ich Dein Problem nicht reproduzieren kann. Was machst Du anders?

    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.Add(dgv)
        dgv.AutoGenerateColumns = False
        With dgv
          With .Columns
            .Add(New DataGridViewTextBoxColumn() _
                 With {.HeaderText = "Info",
                 .DataPropertyName = "Info"})
            .Add(New DataGridViewComboBoxColumn() _
                 With {.HeaderText = "Auswahl",
                 .DataPropertyName = "FK",
                 .ValueMember = "ID",
                 .DisplayMember = "Text",
                 .DataSource = GetMaster(),
                 .DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
            })
          End With
          .DataSource = GetData()
        End With
    
      End Sub
    
      Private dgv As New DataGridView With {.Dock = DockStyle.Fill}
      Private rnd As New Random
    
      Private Function GetData() As DataTable
        Dim dt As New DataTable
        With dt.Columns
          .Add("Info", GetType(String))
          With .Add("FK", GetType(Integer))
            .DefaultValue = 0
          End With
        End With
        For i = 1 To 5
          dt.Rows.Add($"Zeile {i}", rnd.Next(1, 4))
        Next
        Return dt
      End Function
    
      Private Function GetMaster() As List(Of Master)
        Dim l As New List(Of Master)
        l.Add(New Master With {.ID = 0, .Text = $"keine Auswahl"})
        For i = 1 To 3
          l.Add(New Master With {.ID = i, .Text = $"Master {i}"})
        Next
        Return l
      End Function
    
      Class Master
        Public Property ID As Integer
        Public Property Text As String
      End Class
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    Donnerstag, 1. November 2018 09:57

Alle Antworten

  • Hi Christian,
    etwas unklar ist, was Du machst. Die DataGridViewComboBoxColumn hat nur 3 Style-Einstellungen:

    ComboBox
    DropDownButton
    Nothing

    Wie Du ComboBoxStyle = DropDownList einstellst, ist unklar.

    Weiterhin ist zu beachten, dass die neue Zeile (unten) nur ein Platzhalter ist. Erst mit der Änderung in einer Zelle (Spalte) wird ein NewRow ausgeführt und die neue Zeile der Datenquelle hinzugefügt.

    Hier mal eine Demo, mit der ich Dein Problem nicht reproduzieren kann. Was machst Du anders?

    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.Add(dgv)
        dgv.AutoGenerateColumns = False
        With dgv
          With .Columns
            .Add(New DataGridViewTextBoxColumn() _
                 With {.HeaderText = "Info",
                 .DataPropertyName = "Info"})
            .Add(New DataGridViewComboBoxColumn() _
                 With {.HeaderText = "Auswahl",
                 .DataPropertyName = "FK",
                 .ValueMember = "ID",
                 .DisplayMember = "Text",
                 .DataSource = GetMaster(),
                 .DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton
            })
          End With
          .DataSource = GetData()
        End With
    
      End Sub
    
      Private dgv As New DataGridView With {.Dock = DockStyle.Fill}
      Private rnd As New Random
    
      Private Function GetData() As DataTable
        Dim dt As New DataTable
        With dt.Columns
          .Add("Info", GetType(String))
          With .Add("FK", GetType(Integer))
            .DefaultValue = 0
          End With
        End With
        For i = 1 To 5
          dt.Rows.Add($"Zeile {i}", rnd.Next(1, 4))
        Next
        Return dt
      End Function
    
      Private Function GetMaster() As List(Of Master)
        Dim l As New List(Of Master)
        l.Add(New Master With {.ID = 0, .Text = $"keine Auswahl"})
        For i = 1 To 3
          l.Add(New Master With {.ID = i, .Text = $"Master {i}"})
        Next
        Return l
      End Function
    
      Class Master
        Public Property ID As Integer
        Public Property Text As String
      End Class
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    Donnerstag, 1. November 2018 09:57
  • Hallo Peter,
    ich hatte mir eine eigene DropDownColumn gemacht, die eine eigene Combobox als EditingControl verwendet, weil ich dazumals schon das Problem hatte, dass ich DropDownList nicht als Style verwenden konnte. Mein Fehler, dass ich übersehen habe dir das mitzuteilen.

    Untenstehend ist der Code für die eigene Combobox:
    In diesem Code habe ich "Protected Overrides Sub OnSelectedIndexChanged…" hinzugefügt und nun funktioniert es.

        'das EditingControl, mit dem die Zelle editiert werden kann
        Public Class cDataGridViewMyComboBoxEditingControl
            Inherits ComboBox
            Implements IDataGridViewEditingControl
    
            Private dataGridViewControl As DataGridView
            Private valueIsChanged As Boolean = False
            Private rowIndexNum As Integer
    
            Public Function GetEditingControlFormattedValue(ByVal context _
                As DataGridViewDataErrorContexts) As Object _
                Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
    
                Return Me.Text
    
            End Function
    
            Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As  _
                DataGridViewCellStyle) _
                Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
    
                Me.Font = dataGridViewCellStyle.Font
                Me.ForeColor = dataGridViewCellStyle.ForeColor
                Me.BackColor = dataGridViewCellStyle.BackColor
    
            End Sub
    
            Public Function EditingControlWantsInputKey(ByVal key As Keys, _
                ByVal dataGridViewWantsInputKey As Boolean) As Boolean _
                Implements IDataGridViewEditingControl.EditingControlWantsInputKey
    
                ' Let the ComboBoxAutoComplete handle the keys listed.
                Select Case key And Keys.KeyCode
                    Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, _
                        Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
    
                        Return True
    
                    Case Else
                        Return Not dataGridViewWantsInputKey
                End Select
    
            End Function
    
            Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) _
                Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
    
                ' No preparation needs to be done.
    
            End Sub
    
            Protected Overrides Sub OnTextChanged(ByVal eventargs As EventArgs)
    
                ' Notify the DataGridView that the contents of the cell have changed.
                valueIsChanged = True
                Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
                MyBase.OnTextChanged(eventargs)
    
            End Sub
    
            Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs)
    
                If Me.DropDownStyle = ComboBoxStyle.DropDownList Then                   'im Falle einer DropDownList muss bei einer Änderung des SelectedIndex das DGV informiert werden, damit eine NewRow hinzugefügt wird
                    ' Notify the DataGridView that the contents of the cell have changed.
                    valueIsChanged = True
                    Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
                End If
    
                MyBase.OnSelectedIndexChanged(e)
            End Sub
    ''''weiterer Code ..... End Class
    mfg


    Christian Tauschek

    Donnerstag, 1. November 2018 11:55