【问题标题】:Select only one checkbox from multiple checkbox in a row from DataGridView从 DataGridView 的一行中的多个复选框中仅选择一个复选框
【发布时间】:2019-09-29 05:09:12
【问题描述】:

我将 DataGridView 与 TableAdapter 中的 DataSource 一起使用,并添加 5 个类型为 DataGridViewCheckBoxColumn 的未绑定列。

他们是:"lima","empat","tiga","dua","satu"

我需要做什么,在选中复选框“lima”时,在同一行中,其余复选框变为未选中或只能选择同一行中的一个复选框

这是我在CellValueChanged 活动中写下的内容:

   Private Sub DataGridView3_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView3.CellValueChanged
        If DataGridView3.CurrentRow IsNot Nothing Then
            Dim SelectedColumnName = DataGridView3.Columns(DataGridView3.CurrentCellValue.ColumnIndex).Name

            If e.ColumnIndex = DataGridView3.Columns("lima").Index OrElse _
               e.ColumnIndex = DataGridView3.Columns("empat").Index OrElse _
               e.ColumnIndex = DataGridView3.Columns("tiga").Index OrElse _
               e.ColumnIndex = DataGridView3.Columns("dua").Index OrElse _
               e.ColumnIndex = DataGridView3.Columns("satu").Index Then

                Dim Row = CType((CType(DataGridView3.DataSource.Current, DataRowView)).Row, DataRow)

                If SelectedColumnName = "lima" Then
                    If DataGridView3.CurrentRowCellValue("lima") = "True" Then
                        Row.Item("empat") = False
                        Row.Item("tiga") = False
                        Row.Item("dua") = False
                        Row.Item("satu") = False
                    End If

                   'and so..on 

                ElseIf SelectedColumnName = "satu" Then
                    If DataGridView3.CurrentRowCellValue("satu") = "True" Then
                        Row.Item("lima") = False
                        Row.Item("empat") = False
                        Row.Item("tiga") = False
                        Row.Item("dua") = False
                    End If

                End If

                DataGridView3.CurrentCell = DataGridView3(e.ColumnIndex, e.RowIndex)
            End If
            End If

    End Sub

这是模块中CurrentCellCurrentRowCellValue的函数

<System.Diagnostics.DebuggerStepThrough()> _
<Runtime.CompilerServices.Extension()> _
Function CurrentRowCellValue(ByVal sender As DataGridView, ByVal ColumnName As String) As String
    Dim Result As String = ""
    If Not sender.Rows(sender.CurrentRow.Index).Cells(ColumnName).Value Is Nothing Then
        Result = sender.Rows(sender.CurrentRow.Index).Cells(ColumnName).Value.ToString
    End If
    Return Result
End Function

<System.Diagnostics.DebuggerStepThrough()> _
<Runtime.CompilerServices.Extension()> _
Function CurrentCellValue(ByVal sender As DataGridView) As DataGridViewCell
    Return sender(sender.Columns(sender.CurrentCell.ColumnIndex).Index, sender.CurrentRow.Index)
End Function

这是来自CurrentCellDirtyStateChanged事件

Private Sub DataGridView3_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView3.CurrentCellDirtyStateChanged
    If TypeOf DataGridView3.CurrentCell Is DataGridViewCheckBoxCell Then
        DataGridView3.CommitEdit(DataGridViewDataErrorContexts.Commit)
    End If
End Sub

我已经将 DataGridView 的 ReadOnly 属性设置为 False。问题是我仍然可以检查同一行中的所有复选框。

有人可以就我在这里做错了什么提供建议吗?

谢谢

【问题讨论】:

    标签: vb.net winforms visual-studio-2010 checkbox datagridview


    【解决方案1】:

    一些提示:

    • 在使用checkBoxs 时,请参阅this link 关于CellValuechanged 事件
    • 如果它们是未绑定的列,则无法通过 DataSource.Current 行更改值:表没有 lima、empat 的定义...

    这个解决方法(使用CellContentClick)对我有用(不需要扩展方法和CurrentCellDirtyStateChanged 事件):


     Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView3.CellContentClick
    
            Dim checkboxIndexes As New List(Of Integer)
            checkboxIndexes.Add(DataGridView3.Columns("lima").Index)
            checkboxIndexes.Add(DataGridView3.Columns("empat").Index)
            checkboxIndexes.Add(DataGridView3.Columns("tiga").Index)
            checkboxIndexes.Add(DataGridView3.Columns("dua").Index)
            checkboxIndexes.Add(DataGridView3.Columns("satu").Index)
    
            If checkboxIndexes.Contains(e.ColumnIndex) Then
            'check for false value because event occurs before row is validated
                If DataGridView3.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False Then
                    For Each index In checkboxIndexes
                        If index <> e.ColumnIndex Then
                            DataGridView3.Rows(e.RowIndex).Cells(index).Value = False
                        End If
                    Next
                End If
            End If
        End Sub
    

    【讨论】:

    • 是的,它是这样工作的......!感谢代码和链接参考:)
    【解决方案2】:

    我对之前添加的代码进行了改进,以实现我在不同列中检查同一行的复选框的目标。它对我有用。

    Private Sub Grilla_CellClick(sender As Object, e As Telerik.WinControls.UI.GridViewCellEventArgs) Handles Grilla.CellClick
    
        Dim checkboxIndexes As New List(Of Integer)
        checkboxIndexes.Add(Grilla.Columns("Select").Index)
        checkboxIndexes.Add(Grilla.Columns("Select1").Index)
    
    
        If checkboxIndexes.Contains(e.ColumnIndex) Then
            'check for false value because event occurs before row is validated
            If Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False Then
                For Each index In checkboxIndexes
                    If index <> e.ColumnIndex Then
                        'Do nothing here
                    Else
                        If Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False Then
                            Grilla.Rows(e.RowIndex).Cells(index).Value = True
                        Else
                            Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False
                        End If
    
                    End If
                Next
    
            Else
    
                If Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = True Then
                    For Each index In checkboxIndexes
                        If index <> e.ColumnIndex Then
                            'Do nothing here
                        Else
                            If Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False Then
                                Grilla.Rows(e.RowIndex).Cells(index).Value = True
                            Else
                                Grilla.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = False
                            End If
    
                        End If
                    Next
                End If
    
            End If
        End If
    
        Grilla.TableElement.Update(GridUINotifyAction.DataChanged)
    
    End Sub
    

    【讨论】:

    • 能否请您简要解释一下改进之处?
    • 对不起,如果我不够清楚,我的意思是我根据我的需要调整了它,这些是为了能够选中和取消选中,在这种情况下,同一行中的 2 个复选框在它们之间独立.
    • 这是 OP 问题的答案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2023-03-13
    • 2018-02-27
    相关资源
    最近更新 更多