DazEvans
DazEvans

Reputation: 149

Dual check box selection vb / winform

I am after a little bit of help:

I have a datagridview control where I add another couple of columns (as check boxes) in order to select multiple rows. When I select the first checkbox column I want the second to be selected automatically, but can then be de-selected if required. And if the first checkbox is deselected, the 2nd is auto deselected too.

I have this working with the following code:

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

Unfortunately, wen the datagridview is refreshed, the column indexes are incremented, and the column indexes for the 2 check box columns are now 2 and 3.

I would like to be able to refer to them by name. They are declared in the sub that refreshes the datagridview:

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

but the System.Windows.Forms.DataGridViewCellEventArgs class does not allow me to select column name.

Any ideas and suggestions will be greatly appreciated!

Edit: More in depth code segment:

 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

I am unsure why that doesn't work. Each time the calendar control is changed it refreshes the datagridview, which is increasing the column index.

Upvotes: 1

Views: 412

Answers (1)

David Hall
David Hall

Reputation: 33163

You can use the column index provided by the DataGridViewCellEventArgs class to retrieve the column and from that get the name to compare.

So something like:

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

For referencing the columns within your code to toggle the CheckBoxes, you can very happily use the names, and in fact do not need the index provided by the event args. The event args index appears to only be used to check that one of your desired columns was selected.

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

Although the code above should work it appears that something odd is happening with your grid. A quick solution is to instead of using the .Add() to use the .Insert() method of the DataGridView, which provided an index parameter, allowing you to directly control where your column goes.

Upvotes: 1

Related Questions