请注意:这个问题是关于DataGridViewCheckBoxColumn
控件中的DataGridView
- 而不是普通CheckBox
控件。
我有一个winforms应用,其中包含一个带有三个复选框(DataGridView
)列的DataGridViewCheckBoxColumn
。我想模仿radiobuttons即。一次只检查一个复选框。单击一个时,我可以关闭网格中的其他复选框,如下所示:
Private Sub dgvNormalReports_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvNormalReports.CellClick
If mblnSuppressUI Then Exit Sub
mblnSuppressUI = True
If e.ColumnIndex >= 0 And e.ColumnIndex <= dgvNormalReports.ColumnCount - 1 And e.RowIndex >= 0 And e.RowIndex <= dgvNormalReports.Rows.Count - 1 Then
Select Case dgvNormalReports.Columns(e.ColumnIndex).Name
Case "dclLeaveOnThisList", "dclPrintLetter", "dclNoLetterNeeded" 'mimic radiobutton - turn off other checkboxes
dgvNormalReports.Rows(e.RowIndex).Cells("dclLeaveOnThisList").Value = False
dgvNormalReports.Rows(e.RowIndex).Cells("dclPrintLetter").Value = False
dgvNormalReports.Rows(e.RowIndex).Cells("dclNoLetterNeeded").Value = False
'N.B. current cell's checked status is changed AFTER this event
Case Else
'ignore
End Select
End If
mblnSuppressUI = False
End Sub
我遇到的问题是,如果用户点击已经选中的复选框,它将被取消选中,然后检查三个复选框中的任何一个。我总是希望一个(并且只有一个)复选框一直打勾。
答案 0 :(得分:2)
使用CurrentCellDirtyStateChanged
事件处理程序。
Private Sub dgvNormalReports_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles dgvNormalReports.CurrentCellDirtyStateChanged
If Me.dgvNormalReports.IsCurrentCellDirty = True Then
If Me.dgvNormalReports.CurrentCell.OwningColumn.GetType() = GetType(DataGridViewCheckBoxColumn) Then
If Me.dgvNormalReports.CurrentCell.Value = False Then
'Update only if changed from false to true
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclLeaveOnThisList") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclLeaveOnThisList").Value = False
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclPrintLetter") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclPrintLetter").Value = False
If Me.dgvNormalReports.CurrentCell.OwningColumn.Name.Equals("dclNoLetterNeeded") = false Then Me.dgvNormalReports.CurrentRow.Cells("dclNoLetterNeeded").Value = False
Me.dgvNormalReports.CommitEdit(DataGridViewDataErrorContexts.Commit)
Else
'Prevent changes
Me.dgvNormalReports.CancelEdit()
End If
End If
End If
End Sub
如果您在datagridview
中有预定义的列,则可能会更好地使用VisualStudio列对象生成的列:
Me.dclLeaveOnThisList.Name
Me.dclPrintLetter.Name
Me.dclNoLetterNeeded.Name
答案 1 :(得分:1)
第一步,编辑三个DataGridView列并将每个列属性ReadOnly设置为true (这将阻止用户更改值)
和第二,使用下面的代码
Private Sub dgvNormalReports_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvNormalReports.CellClick
If mblnSuppressUI Then Exit Sub
mblnSuppressUI = True
If e.ColumnIndex >= 0 And e.ColumnIndex <= dgvNormalReports.ColumnCount - 1 And e.RowIndex >= 0 And e.RowIndex <= dgvNormalReports.Rows.Count - 1 Then
Dim tmpColName As String = dgvNormalReports.Columns(e.ColumnIndex).Name
With dgvNormalReports.Rows(e.RowIndex)
Select Case tmpColName
Case "dclLeaveOnThisList", "dclPrintLetter", "dclNoLetterNeeded" 'mimic radiobutton - turn off other checkboxes
'Unchecked all checkboxes besides the selected one
If tmpColName <> "dclLeaveOnThisList" Then .Cells("dclLeaveOnThisList").Value = False
If tmpColName <> "dclPrintLetter" Then .Cells("dclPrintLetter").Value = False
If tmpColName <> "dclNoLetterNeeded" Then .Cells("dclNoLetterNeeded").Value = False
'Ensures that the selected cell is checked
.Cells(e.ColumnIndex).Value = True
End Select
End With
End If
mblnSuppressUI = False
End Sub
答案 2 :(得分:1)
您可以结合使用这些DataGridView事件:
您可以使用 CellValueChanged 而不是 CellClick ,因为单击单元格的任何部分时会发生CellClick事件,包括边框和填充(MSDN)。 / p>
CurrentCellDirtyStateChanged 事件在单击CheckBox时提交更改。
CellBeginEdit 中的代码阻止用户修改已检查的CheckBox。
这是一个例子:
Private Sub DataGridView1_CellValueChanged(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
With Me.DataGridView1
.CurrentCell.Value = True
If .Columns(e.ColumnIndex).Name = "dgvchkOptionA" Then
.Rows(e.RowIndex).Cells("dgvchkOptionB").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionC").Value = False
ElseIf .Columns(e.ColumnIndex).Name = "dgvchkOptionB" Then
.Rows(e.RowIndex).Cells("dgvchkOptionA").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionC").Value = False
ElseIf .Columns(e.ColumnIndex).Name = "dgvchkOptionC" Then
.Rows(e.RowIndex).Cells("dgvchkOptionA").Value = False
.Rows(e.RowIndex).Cells("dgvchkOptionB").Value = False
End If
End With
End Sub
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If Me.DataGridView1.IsCurrentCellDirty Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
Private Sub DataGridView1_CellBeginEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
With Me.DataGridView1
If .CurrentCell Is .Rows(e.RowIndex).Cells(e.ColumnIndex) And _
.CurrentCell.Value Then e.Cancel = True
End With
End Sub