1

我正在寻求一点帮助:

我有一个 datagridview 控件,我在其中添加了另外几列(作为复选框)以选择多行。当我选择第一个复选框列时,我希望自动选择第二个复选框,但如果需要,可以取消选择。如果第一个复选框被取消选中,第二个复选框也会自动取消选中。

我有这个使用以下代码:

Private Sub dgvBikeAvailability_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvBikeAvailability.CellContentClick

    Debug.Print("Row index = " + e.RowIndex.ToString + ". Column index = " + e.ColumnIndex.ToString + ". Column Name = ")
    'Debug.Print()
    'when a bike is selected, a helmet is automatically selected, but can be deselected if the customer requires
    If e.ColumnIndex = 0 Then
        dgvBikeAvailability.Rows(e.RowIndex).Cells(0).Value = Not dgvBikeAvailability.Rows(e.RowIndex).Cells(0).Value
        dgvBikeAvailability.Rows(e.RowIndex).Cells(1).Value = dgvBikeAvailability.Rows(e.RowIndex).Cells(0).Value
    End If

End Sub

不幸的是,当刷新 datagridview 时,列索引增加,2 个复选框列的列索引现在是 2 和 3。

我希望能够按名称引用它们。它们在刷新 datagridview 的 sub 中声明:

colBikeSelectionCheckBox.HeaderText = "Select Bike"    
colBikeSelectionCheckBox.Name = "colSelectBike")
colHelmetCheckBox.Name = "colSelectHelmet"
dgvBikeAvailability.Columns.Add(colHelmetCheckBox)

但 System.Windows.Forms.DataGridViewCellEventArgs 类不允许我选择列名。

任何想法和建议将不胜感激!

编辑:更深入的代码段:

 Private Sub frmBikeHire_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    refreshGrid()
    getStaffMember()
End Sub

'loads and refreshes the dgv
Private Sub refreshGrid()
    Dim i As Integer

    'initially fill in the rental dates for current day
    txtDateFrom.Text = CStr(MonthCalendar1.SelectionRange.Start)
    txtDateTo.Text = CStr(MonthCalendar1.SelectionRange.End)

    'grab data from DB, set as dgv datasource
    startDate = CStr(MonthCalendar1.SelectionRange.Start)
    endDate = CStr(MonthCalendar1.SelectionRange.End)
    dtBikeAvailability = sqlFuncDB_getDataTable("SELECT * FROM tb_bikeDetail WHERE bikeid NOT IN (SELECT DISTINCT bikeid FROM tb_bikemovements WHERE bikeMovementDate BETWEEN '" + func_convertDateSQLSERVER(startDate) + "' AND '" + func_convertDateSQLSERVER(endDate) + "') AND bikeid NOT IN (SELECT tb_bikemovements.bikeid FROM tb_bikemovements JOIN (SELECT bikeid, max(bikemovementdate) bmd FROM tb_bikemovements WHERE bikemovementdate < '" + func_convertDateSQLSERVER(startDate) + "' group by bikeid) lastmove ON lastmove.bikeid=tb_bikemovements.bikeid AND lastmove.bmd=tb_bikemovements.bikemovementdate WHERE bikeMovementType = '0')")
    dvBikeAvailability = New DataView(dtBikeAvailability)
    dgvBikeAvailability.DataSource = dvBikeAvailability

    'switch off all columns
    For i = 0 To dgvBikeAvailability.Columns.Count - 1
        dgvBikeAvailability.Columns(i).Visible = False
    Next

    'displays only relevant column(s)
    dgvBikeAvailability.Columns("bikeName").Visible = True
    dgvBikeAvailability.Columns("bikeName").HeaderText = "Bike Name"
    dgvBikeAvailability.Columns("bikeStyle").Visible = True
    dgvBikeAvailability.Columns("bikeStyle").HeaderText = "Bike Style"
    dgvBikeAvailability.Columns("bikeColour").Visible = True
    dgvBikeAvailability.Columns("bikeColour").HeaderText = "Bike Colour"

    'remove this line for program deployment
    dgvBikeAvailability.Columns("bikeID").Visible = True
    dgvBikeAvailability.Columns("bikeID").HeaderText = "Bike Number"

    'add new check box column for selecting the bike 
    Dim colBikeSelectionCheckBox As New DataGridViewCheckBoxColumn
    colBikeSelectionCheckBox.DataPropertyName = "PropertyName"
    colBikeSelectionCheckBox.HeaderText = "Select Bike"
    colBikeSelectionCheckBox.Name = "colSelectBike"
    dgvBikeAvailability.Columns.Add(colBikeSelectionCheckBox)

    'add new column for selecting helmet - consider adding as default setting
    Dim colHelmetCheckBox As New DataGridViewCheckBoxColumn
    colHelmetCheckBox.DataPropertyName = "PropertyName"
    colHelmetCheckBox.HeaderText = "Helmet?"
    colHelmetCheckBox.Name = "colSelectHelmet"
    dgvBikeAvailability.Columns.Add(colHelmetCheckBox)

    dgvBikeAvailability.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

End Sub

Private Sub MonthCalendar1_DateChanged(sender As System.Object, e As System.Windows.Forms.DateRangeEventArgs) Handles MonthCalendar1.DateChanged
    refreshGrid()
End Sub

Private Sub dgvBikeAvailability_CellClick(sender As Object, e As     System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvBikeAvailability.CellClick
    Debug.Print("Row index = " + e.RowIndex.ToString + ". Column index = " + e.ColumnIndex.ToString + ". Column Name = " + dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").OwningColumn.ToString)

    If dgvBikeAvailability.Columns(e.ColumnIndex).Name = "colSelectBike" Then
        dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value = Not dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value
        dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectHelmet").Value = dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value
    End If

End Sub

我不确定为什么这不起作用。每次更改日历控件时,它都会刷新 datagridview,这会增加列索引。

4

1 回答 1

1

您可以使用DataGridViewCellEventArgs类提供的列索引来检索列,并从中获取要比较的名称。

所以像:

If dgvBikeAvailability.Columns(e.ColumnIndex).Name == "colSelectBike" Then
    ' Your logic here
End If

为了引用代码中的列来切换复选框,您可以非常愉快地使用名称,实际上不需要事件参数提供的索引。事件参数索引似乎仅用于检查是否选择了所需的列之一。

dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value = Not dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value
dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectHelmet").Value = dgvBikeAvailability.Rows(e.RowIndex).Cells("colSelectBike").Value

尽管上面的代码应该可以工作,但您的网格似乎发生了一些奇怪的事情。一个快速的解决方案是代替使用DataGridView.Add().Insert()方法,它提供了一个索引参数,允许您直接控制列的位置。

于 2013-04-25T12:18:37.007 回答