双复选框选择vb / winform

时间:2013-04-25 12:05:19

标签: vb.net winforms datagridview

我正在寻求一些帮助:

我有一个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。

我希望能够通过名字来引用它们。它们在sub中声明,刷新datagridview:

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,这会增加列索引。

1 个答案:

答案 0 :(得分:1)

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

类似于:

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

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

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

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