dcsimg
Results 1 to 13 of 13
  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Resolved [RESOLVED] DataGridView ComboBox returning System.Data.DataRowView

    I have a DataGridView and I have populated a DataGridViewComboBoxColumn with a DataTable.

    Clicking the Combobox very slowly allows the selection to be made and it returns a result from the pulldown menu. However, clicking quickly returns System.Data.DataRowView. I have tried unsuccessfully to test for SelectedIndex <> -1, SelectedValue Is NotNothing, Is NotDBNull etc but the issue persists. Please let me know what I'm missing. Thank you in advance!

    Maybe I'm calling out the wrong Control type? It's a DataGridViewComboBoxCell and I'm checking for a standard ComboBox? (I didn't know how to test for DataGridViewComboBoxCell control type.)

    Code:
        
    Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            If TypeOf e.Control Is ComboBox Then
                Dim CmbBx As ComboBox = CType(e.Control, ComboBox)
                If (CmbBx IsNot Nothing) Then
                    'Remove an existing event-handler
                    RemoveHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
    
                    'Add the event handler. 
                    AddHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
                End If
            End If
        End Sub
    
        Private Sub DGVComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim CmbBx As ComboBox = CType(sender, ComboBox)
            'Display selected value
            If CmbBx IsNot Nothing Then
                Dim ItemNo As String = Nothing
                If CmbBx.SelectedIndex <> -1 Then
                    ItemNo = CmbBx.Text
                    MessageBox.Show("POItem: " & ItemNo)
                End If
            End If
        End Sub

  2. #2
    Addicted Member
    Join Date
    Aug 2017
    Location
    Nigeria
    Posts
    234

    Re: DataGridView ComboBox returning System.Data.DataRowView

    okay, using selectedIndex or selected item will always return a DataRow for you. So rather use its
    Code:
    SelectedItem.Text
    method to get the item that is displayed and you have clicked
    Nothing I post is Self Reliable. Use it at your own risk

  3. #3
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    98,907

    Re: DataGridView ComboBox returning System.Data.DataRowView

    There is a proper way to use a combo box column in a DataGridView. You bind your list to the column and you assign the name of the property or column you want pushed to the grid's data source to the ValueMember property. Here's one I prepared earlier:

    http://www.vbforums.com/showthread.p...a-DataGridView
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    Thank you TATARPRO and JMC (I had no idea I could just call Me.Column1 I was looping through the Comboboxes in Column1 and populating them one at at time!)

    However, I'm still getting the System.Data.DataRowView return if I accidentally click inside the cell before clicking the down arrow of the cell. I think this is working exactly as JMC described in his other post. The ComboBox is just overlaying the cell and then it pushes its data down to the cell. I resolved the issue this, but I think there must be a better method:

    Code:
    Private Sub PopComboBox(sender As Object, e As EventArgs, JobID As String)
    
            Dim dt As New DataTable
            Dim conStr As String = MyConnectionStr
            Dim sqCon As New SqlConnection(conStr)
            sqCon.Open()
            Dim Adapter As New SqlDataAdapter("SELECT ItemID FROM SageJobs WHERE JobID = '" & JobID & "'", sqCon)
            Adapter.Fill(dt)
            sqCon.Close()
    
            Me.BindingSource1.DataSource = dt
            Me.Column1.ValueMember = "ItemID"
            Me.Column1.DisplayMember = "ItemID"
            Me.Column1.DataSource = dt
    
            Me.DataGridView1.Columns("POItems").ReadOnly = False    'Now make only this column editable
    
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            If TypeOf e.Control Is ComboBox Then
                Dim CmbBx As ComboBox = CType(e.Control, ComboBox)
                If (CmbBx IsNot Nothing) Then
                    'Remove an existing event-handler
                    RemoveHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
    
                    'Add the event handler. 
                    AddHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
                End If
            End If
        End Sub
    
        Private Sub DGVComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim CmbBx As ComboBox = CType(sender, ComboBox)
            'Display selected value
            If CmbBx IsNot Nothing Then
                Dim ItemNo As String = Nothing
                If CmbBx.Text <> "" And CmbBx.Text <> "System.Data.DataRowView" Then '<--This seems silly, i'm trying to say if nothing was selected then ignore this
                    ItemNo = CmbBx.Text
                    MessageBox.Show("POItem: " & ItemNo)
                    'do Stuff
                End If
            End If
        End Sub

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    98,907

    Re: DataGridView ComboBox returning System.Data.DataRowView

    You're definitely not giving us the whole story here. What's up with the parameters of that PopComboBox method? It looks like it is/was an event handler and you have added another parameter for some reason without removing the others. Why are you handling the EditingControlShowing event of the grid and SelectedIndexChanged event of the editing control in the first place? If we understand what you're trying to achieve, we can determine the best way to achieve it.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    I corrected the PopComboBox method to remove the sender and EventArgs since they are not used. Only argument is JobID now, sorry I haven't refactored everything yet.

    The purpose of the application is to match customer purchase order line items to our internal quote line items. The DataGridView left side columns are Purchase Order line item columns. Right side columns are Quote line items columns.

    I added the left side columns manually in Design mode. Those manually added columns remain unpopulated with the left most column being a combobox. The combobox is filled with line items from the purchase order for the user to choose. The right side columns of the DataGridView are populated from the database at runtime. Left side columns are then filled in when the user chooses a purchase order line item from the pulldown menu.

    All of this functions as expected, the only issue is that the Combobox will return System.Data.DataRowview instead of data depending on how fast and accurate your mouseclick is. I'm just trying to weed out bad mouse clicks.

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    98,907

    Re: DataGridView ComboBox returning System.Data.DataRowView

    As far as I can tell, there's no need for any of the code you have posted here. Simply bind the combo box column properly and handle the CellValueChanged event of the grid to detect changes to cells in that column. Use the Value of that cell to get the corresponding DataRow and then populate the other cells in that row from that. You're trying to fix a problem that you have created by doing the wrong thing in the first place.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    Both CellValueChanged and CellEndEdit require two inputs from the user. The user must hit enter or otherwise provide additional input after selecting a value from the Combobox to complete the edit.

    The purpose of using DataGridView1.EditingControlShowing and using it to add a handler to another method is to capture the selected index as it is changed. I'm trying to mimic the behavior of a Combobox in a form and have it immediately recognize the value selected and update the grid.

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    98,907

    Re: DataGridView ComboBox returning System.Data.DataRowView

    OK, so you want the other grid columns to update without actually changing the Value in the cell containing the ComboBox. I can test that and put together a demo. Just keep in mind that, if you do that, you'll need to be able to reset those cells if the user cancels an edit. If, for instance, the first item in the ComboBox is selected and the user starts editing that cell and selects the second item, you will then update the other cells in the row to correspond to the second item. If the user then cancels the edit, that ComboBox cell will still contain the first item so you'd need to reset the other columns back to the first item too.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    Yes, I believe we are on the same page. I already have the Combobox selection updating the grid columns as you described:

    Column index 0 is the Combobox. Selecting Item 1 in the Combobox updates columns 1-5, leaving column 0 (the Combobox) in tact with item 1 selected.
    Selecting Item 2 in the Combobox repopulates columns 1-5 with new data and leaves Combobox 2 in tact with item 2 selected.

    This all works well. It's just the quirky nature of the Combobox iteslf and testing for a bad mouseclick that had me stumped. Here is the full working code if it will save you some time. I marked the exact code that I was questioning as CHEESY:

    Code:
       Private Sub Form162_SalesRelease_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Fill a DataTable
            RemoveHandler QRevCmbBx.SelectedIndexChanged, AddressOf QRevCmbBx_SelectedIndexChanged
    
            Dim sqCon As New SqlClient.SqlConnection(MyConnectionStr)
            Dim sqCmd As New SqlClient.SqlCommand
            Dim Sql As String = Nothing
            Dim dt As New DataTable
            Dim QuoteNo As String = Me.QuoteNoTxtBx.Text
    
            sqCmd.Connection = sqCon            'create the DB connection 
            Sql = "SELECT QuoteRev FROM QuoteForm WHERE QuoteNo = '" & QuoteNo & "'"
            sqCon.Open()                        'open the connection
    
            'Dim dtF As New DataTable
            Dim AdapterW As New SqlDataAdapter
    
            AdapterW.SelectCommand = New SqlCommand(Sql, sqCon)
            AdapterW.Fill(dt) 'Fills a Dataset with the sql command above
            sqCon.Close() 'close the connection
            '''''''''''''''''''''''''''
    
            'Fill a ComboBox with a DataTable
            Me.QRevCmbBx.DataSource = dt.DefaultView
            Me.QRevCmbBx.DisplayMember = "QuoteRev"
            Me.QRevCmbBx.SelectedIndex = -1
    
            AddHandler QRevCmbBx.SelectedIndexChanged, AddressOf QRevCmbBx_SelectedIndexChanged
    
        End Sub
    
        Private Sub QRevCmbBx_SelectedIndexChanged(sender As Object, e As EventArgs) Handles QRevCmbBx.SelectedIndexChanged
    
            If Me.QRevCmbBx.SelectedIndex <> -1 Then
    
                'Populate the Grid:
                Dim sqCon As New SqlClient.SqlConnection(MyConnectionStr)
                Dim sqCmd As New SqlClient.SqlCommand
                Dim dt As New DataTable
    
                Dim QuoteNo As String = Me.QuoteNoTxtBx.Text
                Dim QuoteRev As String = Me.QRevCmbBx.Text
    
                'Fill a DataTable
                Dim Sql As String = "SELECT * FROM QuoteForm WHERE QuoteNo = '" & QuoteNo & "' AND QuoteRev = '" & QuoteRev & "'"
                sqCmd.Connection = sqCon            'create the DB connection 
                sqCon.Open()                        'open the connection
    
                Dim Adapter As New SqlDataAdapter
                Adapter.SelectCommand = New SqlCommand(Sql, sqCon)
                Adapter.Fill(dt) 'Fills a Dataset with the sql command above
                sqCon.Close() 'close the connection
    
                Dim Ser(15) As String
                Dim Desc(15) As String
                Dim Turn(15) As String
                Dim QTY(15) As String
                Dim Price(15) As String
                Dim PType(15) As String
                Dim SubT(15) As String
    
                Dim dr() As DataRow = dt.Select("QuoteRev = '" & QuoteRev & "'")
                Dim dt2 As New DataTable
    
                'Add new columns to the datatable
                If Not dt2.Columns.Contains("Ser") Then
                    dt2.Columns.Add("Ser")
                End If
                If Not dt2.Columns.Contains("Desc") Then
                    dt2.Columns.Add("Desc")
                End If
                If Not dt2.Columns.Contains("Turn") Then
                    dt2.Columns.Add("Turn")
                End If
                If Not dt2.Columns.Contains("QTY") Then
                    dt2.Columns.Add("QTY")
                End If
                If Not dt2.Columns.Contains("Sub") Then
                    dt2.Columns.Add("Sub")
                End If
                If Not dt2.Columns.Contains("PType") Then
                    dt2.Columns.Add("PType")
                End If
                If Not dt2.Columns.Contains("Price") Then
                    dt2.Columns.Add("Price")
                End If
    
                'Populate quote columns in the new dt2 from row data in dt
                For i = 0 To 14 Step 1
                    QTY(i) = dr(0).Field(Of String)("QTY" & i + 1)
                    If QTY(i) <> "" Then
                        Dim newRow As DataRow = dt2.NewRow
                        newRow("QTY") = QTY(i)
                        Ser(i) = dr(0).Field(Of String)("Ser" & i + 1)
                        newRow("Ser") = Ser(i)
                        Desc(i) = dr(0).Field(Of String)("Desc" & i + 1)
                        newRow("Desc") = Desc(i)
                        Turn(i) = dr(0).Field(Of String)("Turn" & i + 1)
                        newRow("Turn") = Turn(i)
                        SubT(i) = dr(0).Field(Of String)("Sub" & i + 1) 'Ext Price
                        newRow("Sub") = SubT(i)
                        PType(i) = dr(0).Field(Of String)("PType" & i + 1) 'Unit
                        newRow("PType") = PType(i)
                        Price(i) = dr(0).Field(Of String)("Price" & i + 1)
                        newRow("Price") = Price(i)
                        dt2.Rows.Add(newRow)
                    End If
                Next
    
                Me.DataGridView1.DataSource = dt2
                Dim grid As DataGridView = DataGridView1
                With grid
                    .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
                End With
    
                Call RadBtn_CheckedChanged(sender, e)
    
                For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
                    Me.DataGridView1.Rows(i).Cells("Ser").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("Desc").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("Turn").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("QTY").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("Sub").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("PType").Style.BackColor = Color.LightGreen
                    Me.DataGridView1.Rows(i).Cells("Price").Style.BackColor = Color.LightGreen
                Next
    
            End If
    
        End Sub
    
        Private Sub RadBtn_CheckedChanged(sender As Object, e As EventArgs) Handles DesRadBtn.CheckedChanged, FabRadBtn.CheckedChanged, AssyRadBtn.CheckedChanged, PartsRadBtn.CheckedChanged, EngRadBtn.CheckedChanged
    
            Dim RADBtn As RadioButton = ServGrpBx.Controls.OfType(Of RadioButton).FirstOrDefault(Function(r) r.Checked = True)
            Dim QuoteNo As String = Me.QuoteNoTxtBx.Text
            Dim Sufx As String = Nothing
            Me.SufxTxtBx.Text = Sufx
    
            If Not IsNothing(RADBtn) Then
                If RADBtn Is DesRadBtn Then
                    Sufx = "D"
                ElseIf RADBtn Is FabRadBtn Then
                    Sufx = "F"
                ElseIf RADBtn Is AssyRadBtn Then
                    Sufx = "A"
                ElseIf RADBtn Is PartsRadBtn Then
                    Sufx = "P"
                ElseIf RADBtn Is EngRadBtn Then
                    Sufx = "E"
                End If
    
                If DataGridView1.Rows.Count > 0 Then
                    For Each row As DataGridViewRow In DataGridView1.Rows
                        row.Cells("POItems").Value = Nothing
                        row.Cells("JobID").Value = Nothing
                        row.Cells("PODesc").Value = Nothing
                        row.Cells("POQTY").Value = Nothing
                        row.Cells("POUnitEa").Value = Nothing
                        row.Cells("POExt").Value = Nothing
                    Next
                End If
    
                Me.SufxTxtBx.Text = Sufx
                Dim JobID As String = QuoteNo & Sufx
                Dim CustPO As String = PullPO(JobID) 'Pulls PO information from dbo.SageJobs
                Me.PONOTxtBx.Text = CustPO
                Call PopComboBox(JobID)
            End If
    
        End Sub
    
        Private Function PullPO(JobID As String)
    
            'Read Single Value from database
            Dim sqCon As New SqlClient.SqlConnection(MyConnectionStr)
            Dim sqCmd As New SqlClient.SqlCommand
            Dim SageSO As String = Nothing
            Dim CustPO As String = Nothing
            Try
                sqCmd = sqCon.CreateCommand()
                sqCmd.CommandText = "SELECT SageSO FROM SageJobs WHERE JobID = '" & JobID & "'"
                sqCon.Open()
                SageSO = sqCmd.ExecuteScalar() 'Returns a single value
                sqCon.Close()
            Catch ex As Exception
                MessageBox.Show("No SageSO found for " & JobID)
            End Try
    
            Me.SageSOTxtBx.Text = SageSO
    
            Try
                sqCmd = sqCon.CreateCommand()
                sqCmd.CommandText = "SELECT CustPO FROM SageJobs WHERE SageSO = '" & SageSO & "' AND QTY IS NULL"
                sqCon.Open()
                CustPO = sqCmd.ExecuteScalar() 'Returns a single value
                sqCon.Close()
            Catch ex As Exception
                MessageBox.Show("No CustPO found for " & JobID)
            End Try
    
            Return CustPO
    
        End Function
    
        Private Sub PopComboBox(JobID As String)
    
            Dim dt As New DataTable
            Dim conStr As String = QCGMAIN
            Dim sqCon As New SqlConnection(conStr)
            sqCon.Open()
            Dim Adapter As New SqlDataAdapter("SELECT ItemID FROM SageJobs WHERE JobID = '" & JobID & "'", sqCon)
            Adapter.Fill(dt)
            sqCon.Close()
    
            Me.BindingSource1.DataSource = dt
            Me.POItems.ValueMember = "ItemID"
            Me.POItems.DisplayMember = "ItemID"
            Me.POItems.DataSource = dt
    
            Me.DataGridView1.Columns("POItems").ReadOnly = False    'Now make only this column editable
    
    
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            If TypeOf e.Control Is ComboBox Then
                Dim CmbBx As ComboBox = CType(e.Control, ComboBox)
                If (CmbBx IsNot Nothing) Then
                    'Remove an existing event-handler
                    RemoveHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
    
                    'Add the event handler. 
                    AddHandler CmbBx.SelectedIndexChanged, New EventHandler(AddressOf DGVComboBox_SelectedIndexChanged)
                End If
            End If
        End Sub
    
        Private Sub DGVComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
    
            Dim CmbBx As ComboBox = CType(sender, ComboBox)
            Dim ItemID As String = Nothing
            If CmbBx.Text <> "" And CmbBx.Text <> "System.Data.DataRowView" Then '<-- THIS IS KIND OF CHEESY!
                ItemID = CmbBx.Text
                Dim JobID As String = Me.QuoteNoTxtBx.Text & Me.SufxTxtBx.Text
                Dim PODesc As String = Nothing
                Dim POQTY As String = Nothing
                Dim POUnitEa As String = Nothing
                Dim POExt As String = Nothing
    
                Dim sqCon As New SqlClient.SqlConnection(MyConnectionStr)
                Dim sqCmd As New SqlClient.SqlCommand
    
                'Read database
                sqCmd.Connection = sqCon            'create the DB connection 
                sqCon.Open()                        'open the connection
                sqCmd.CommandText = "SELECT LineDesc, QTY, UnitPrice, Amount FROM SageJobs WHERE JobID = '" & JobID & "' AND ItemID = '" & ItemID & "'"
                Dim sqReader As SqlDataReader = sqCmd.ExecuteReader()        'execute the SQL command
                If sqReader.HasRows Then
                    While sqReader.Read()
                        If Not IsDBNull(sqReader.Item("LineDesc")) Then
                            PODesc = sqReader.Item("LineDesc").ToString
                        End If
                        If Not IsDBNull(sqReader.Item("QTY")) Then
                            POQTY = sqReader.Item("QTY").ToString
                        End If
                        If Not IsDBNull(sqReader.Item("UnitPrice")) Then
                            POUnitEa = sqReader.Item("UnitPrice").ToString
                        End If
                        If Not IsDBNull(sqReader.Item("Amount")) Then
                            POExt = sqReader.Item("Amount").ToString
                        End If
                    End While
                End If
                sqReader.Close()       'always close the reader when you're done with it.
                sqCon.Close()
    
                'Populate Sage line item info into Grid row:
                Me.DataGridView1.SelectedRows(0).Cells("JobID").Value = JobID
                Me.DataGridView1.SelectedRows(0).Cells("PODesc").Value = PODesc
                Me.DataGridView1.SelectedRows(0).Cells("POQTY").Value = POQTY
                Me.DataGridView1.SelectedRows(0).Cells("POUnitEa").Value = POUnitEa
                Me.DataGridView1.SelectedRows(0).Cells("POExt").Value = POExt
    
            End If
    
        End Sub
    
        Private Sub DataGridView_CellClick(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
            Dim DGV As DataGridView = sender
            If e.Button = Windows.Forms.MouseButtons.Right Then
                Dim hit As DataGridView.HitTestInfo = DGV.HitTest(e.X, e.Y)
                With DGV
                    .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                    .MultiSelect = False  'Prevents Multiple rows from being selected
                    On Error Resume Next
                    DGV.Rows(hit.RowIndex).Selected = True
                    DGV.ContextMenuStrip.Show(DGV, New Point(hit.RowIndex, hit.ColumnIndex))
                End With
            ElseIf e.Button = Windows.Forms.MouseButtons.Left Then
                Dim hit As DataGridView.HitTestInfo = DGV.HitTest(e.X, e.Y)
                With DGV
                    '.SelectionMode = DataGridViewSelectionMode.CellSelect
                    .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                    .MultiSelect = False
                End With
            End If
        End Sub

  11. #11
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    98,907

    Re: DataGridView ComboBox returning System.Data.DataRowView

    I would change the way you're removing the event handler and see if that solves the issue. Instead of removing and adding in the EditingControlShowing event handler, I would add only there and remove in the CellEndEdit event handler, e.g.
    vb.net Code:
    1. Private editingControl As ComboBox
    2.  
    3. Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    4.     editingControl = TryCast(e.Control, ComboBox)
    5.  
    6.     If editingControl IsNot Nothing Then
    7.         AddHandler editingControl.SelectedIndexChanged, AddressOf editingControl_SelectedIndexChanged
    8.     End If
    9. End Sub
    10.  
    11. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
    12.     If editingControl IsNot Nothing Then
    13.         RemoveHandler editingControl.SelectedIndexChanged, AddressOf editingControl_SelectedIndexChanged
    14.         editingControl = Nothing
    15.     End If
    16. End Sub
    17.  
    18. Private Sub editingControl_SelectedIndexChanged(sender As Object, e As EventArgs)
    19.     '...
    20. End Sub
    In fact, given that you need a field for that anyway, you could simply it further and use WithEvents/Handles:
    vb.net Code:
    1. Private WithEvents editingControl As ComboBox
    2.  
    3. Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    4.     editingControl = TryCast(e.Control, ComboBox)
    5. End Sub
    6.  
    7. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
    8.     editingControl = Nothing
    9. End Sub
    10.  
    11. Private Sub editingControl_SelectedIndexChanged(sender As Object, e As EventArgs) Handles editingControl.SelectedIndexChanged
    12.     '...
    13. End Sub
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    Okay, thank you very much for sticking with it! It's late here so I will try it first thing in the morning.

  13. #13

    Thread Starter
    Lively Member
    Join Date
    Jul 2013
    Posts
    112

    Re: DataGridView ComboBox returning System.Data.DataRowView

    Your second solution was much more elegant so I used it and added a CurrentCellDirtyStateChanged method/handle to commit the edit right when the Combobox selection is made. Now it is behaving like a 'real' Combobox:

    Code:
        Private WithEvents editingControl As ComboBox
    
        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            editingControl = TryCast(e.Control, ComboBox)
        End Sub
    
        Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
            editingControl = Nothing
        End Sub
    
        Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
            If IsNothing(DataGridView1.CurrentCell) Then Exit Sub
            If DataGridView1.IsCurrentCellDirty And TypeOf DataGridView1.CurrentCell Is DataGridViewComboBoxCell Then
                DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
            End If
        End Sub
    
        Private Sub editingControl_SelectedIndexChanged(sender As Object, e As EventArgs) Handles editingControl.SelectedIndexChanged
            Dim CmbBx As ComboBox = TryCast(sender, ComboBox)
            Dim ItemID As String = CmbBx.Text
                   'do stuff
        End Sub
    
        Private Sub DataGridView_CellClick(ByVal sender As Object, ByVal e As MouseEventArgs) Handles DataGridView1.MouseDown
            Dim DGV As DataGridView = sender
            If e.Button = Windows.Forms.MouseButtons.Right Then
                Dim hit As DataGridView.HitTestInfo = DGV.HitTest(e.X, e.Y)
                With DGV
                    .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                    .MultiSelect = False
                End With
            ElseIf e.Button = Windows.Forms.MouseButtons.Left Then
                Dim hit As DataGridView.HitTestInfo = DGV.HitTest(e.X, e.Y)
                With DGV
                    .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                    .MultiSelect = False
                End With
            End If
        End Sub
    As always, thank you for the extraordinary effort. I've learned a lot from you.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width


×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.