1

I am having trouble creating a "SelectAll" checkbox column that actually selects all checkboxes in a ROW not a column. The "SelectALL" column is the third column in the table that i would like to check all the boxes after it in the same ROW. The column names that follow the "SelectALL" column are dynamically generated so the column names are unknown prior to table generation. Here is my code so far:

$CheckAll_click = {
for($i=0;$i -lt $DGV1.RowCount;$i++){
    if($DGV1.Rows[$i].Cells['SelectAll'].Value -eq $true) {
        for($j=3;$j -le $DGV1.ColumnCount;$j++){
            ($DGV1.Rows[$i].Cells | ?{$_.ColumnIndex -eq $j}).Value=$true
        }
    }
    else {
        for($j=3;$j -le $DGV1.ColumnCount;$j++){
            ($DGV1.Rows[$i].Cells | ?{$_.ColumnIndex -eq $j}).Value=$false
        }
    }
}
PJBuckley
  • 13
  • 3

1 Answers1

0

This was harder than I expected. The trick (from here) is to trigger CommitEdit before trying to read the state of the SelectAll checkbox. $Sender and $EventArgs (shortened to $e below for readability) can be helpful parameters when you're trying to find out which checkbox was checked.

@("System.Windows.Forms","System.Drawing") | %{[reflection.assembly]::LoadWithPartialName($_) | Out-Null}
$form = New-Object System.Windows.Forms.Form -Property @{Size=New-Object System.Drawing.Size(900,600)}
$dataGridView = New-Object System.Windows.Forms.DataGridView -Property @{Anchor = "Left,Right,Top,Bottom";Size='870,550'}
@('SelectAll','Col1','Col2') | %{
    $dataGridView.columns.Add( (New-Object Windows.Forms.DataGridViewCheckBoxColumn -Property @{Name=$_; TrueValue=$true; FalseValue=$false})) | Out-Null
}
1..4 | %{
    $dataGridView.Rows.Add((New-Object System.Windows.Forms.DataGridViewRow)) | Out-Null
}

$dataGridView.add_CellContentClick({param($sender,$e)
    if($dataGridView.Rows[$e.RowIndex].Cells[$e.ColumnIndex].OwningColumn.HeaderText -ne 'SelectAll'){return}
    [Windows.Forms.DataGridViewCheckBoxCell] $ChkSelectAll = $dataGridView.Rows[$e.RowIndex].Cells | 
        ?{$_.OwningColumn.HeaderText -eq 'SelectAll'}
    $dataGridView.CommitEdit([Windows.Forms.DataGridViewDataErrorContexts]::Commit) #commits the cahnge you are editing
    $dataGridView.Rows[$e.RowIndex].Cells | ? {$_.GetType().Name -eq 'DataGridViewCheckBoxCell' } | %{
        $_.Value = $ChkSelectAll.Value 
    }
})

$form.Controls.Add($dataGridView)
$form.ShowDialog()
Rich Moss
  • 2,195
  • 1
  • 13
  • 18
  • Where do the $sender and $e variables get set? and how do the get passed to your cell click event? – PJBuckley Dec 13 '19 at 16:42
  • The [DataGridView.CellContentClick](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridview.cellcontentclick?view=netframework-4.8) event is similar to most Winforms events in how it passes a `Sender` object that is receiving the event, and `e` or `EventArgs` which specifies the details of what happened. When you add the Powershell event handler you can specify that `$sender` and `$e` objects will be populated by adding the `param($sender,$e)` line. – Rich Moss Dec 13 '19 at 20:18
  • You can also use the Powershell-specific - [$this and $_](https://stackoverflow.com/questions/51130595/windows-forms-controls-events-in-powershell-use-sender-and-eventargs) [automatic variables](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-6). – Rich Moss Dec 13 '19 at 20:19
  • Ahhh.. The light just turned on. Iv seen those variables in a lot of code but ive always taken that and tried to "solve" for those variables, probably making things twice as hard for me while building this code. Thank you so much for the help! – PJBuckley Dec 16 '19 at 18:11