Home > Net >  Powershell Datagridview: avoid selection of rows based on a value in cell
Powershell Datagridview: avoid selection of rows based on a value in cell

Time:06-08

I have a script that shows cells with various values. If a cell has the value '0' then it should not be possible to select the entire row.

Example

Here, the rows with the numbers 10, 11 and 13 should not be able to select.

I have the following script:

Function GenerateDataGrid
{
 
 For($Index = 1; $Index -le 30; $Index  )
  {

   $Record = [ordered]@{
    Follow = $Index
    Number = Random(0..5)
    }
    $Global:Table  = New-Object 'PSObject' -Property $Record
  }

  $dgvTest.DataSource = [System.Collections.ArrayList]$Global:Table
  $dgvTest.SelectAll()
  $Rows = $dgvTest.SelectedRows
  ForEach ($Row in $Rows)
   {
    if($dgvTest.Rows[$Row.Index].Cells['Number'].Value -eq 0)
     {
      # $dgvTest.Rows[$Row.Index].Readonly = $True    -> Does not work
      # $dgvTest.Rows[$Row.Index].Locked = $True      -> Throws up an error
      # $dgvTest.Rows[$Row.Index].Enabled = $False    -> Throws up an error
      $dgvTest.Rows[$Row.Index].DefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(255, 224, 224, 224)
     }
   }
  $dgvTest.ClearSelection()
}

Function ShowResults
{
 $Rows = $dgvTest.SelectedRows
 Clear-Host
 ForEach ($Row in $Rows)
  {
   $Follow = $dgvTest.Rows[$Row.Index].Cells['Follow'].Value
   $Number = $dgvTest.Rows[$Row.Index].Cells['Number'].Value
   Write-Host "$Follow $Number"
  }     
}

$Global:Table = @()

Add-Type -AssemblyName System.Web
Add-Type -AssemblyName System.Windows.Forms

$frmDataGridTest = New-Object 'System.Windows.Forms.Form'
$btnShow = New-Object 'System.Windows.Forms.Button'
$chkAllItems = New-Object 'System.Windows.Forms.CheckBox'
$btnCancel = New-Object 'System.Windows.Forms.Button'
$dgvTest = New-Object 'System.Windows.Forms.DataGridView'

#
# frmDataGridTest
#
$frmDataGridTest.Controls.Add($btnShow)
$frmDataGridTest.Controls.Add($chkAllItems)
$frmDataGridTest.Controls.Add($btnCancel)
$frmDataGridTest.Controls.Add($dgvTest)
$frmDataGridTest.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$frmDataGridTest.AutoScaleMode = 'Font'
$frmDataGridTest.CancelButton = $btnCancel
$frmDataGridTest.ClientSize = New-Object System.Drawing.Size(281, 464)
$frmDataGridTest.Name = 'frmDataGridTest'
$frmDataGridTest.StartPosition = 'CenterScreen'
$frmDataGridTest.Text = 'Test DatagridView'
#
# btnShow
#
$btnShow.Location = New-Object System.Drawing.Point(106, 385)
$btnShow.Name = 'btnShow'
$btnShow.Size = New-Object System.Drawing.Size(75, 50)
$btnShow.TabIndex = 3
$btnShow.Text = 'Show selected items'
$btnShow.UseVisualStyleBackColor = $True
#
# chkAllItems
#
$chkAllItems.Location = New-Object System.Drawing.Point(22, 13)
$chkAllItems.Name = 'chkAllItems'
$chkAllItems.Size = New-Object System.Drawing.Size(240, 24)
$chkAllItems.TabIndex = 2
$chkAllItems.Text = 'Select or unselect all items'
$chkAllItems.UseVisualStyleBackColor = $True
#
# btnCancel
#
$btnCancel.DialogResult = 'Cancel'
$btnCancel.Location = New-Object System.Drawing.Point(187, 385)
$btnCancel.Name = 'btnCancel'
$btnCancel.Size = New-Object System.Drawing.Size(75, 50)
$btnCancel.TabIndex = 1
$btnCancel.Text = 'Cancel'
$btnCancel.UseVisualStyleBackColor = $True
#
# dgvTest
#
$dgvTest.AllowUserToAddRows = $False
$dgvTest.AllowUserToDeleteRows = $False
$dgvTest.AllowUserToOrderColumns = $True
$dgvTest.AllowUserToResizeRows = $False
$dgvTest.AutoSizeColumnsMode = 'AllCells'
$dgvTest.AutoSizeRowsMode = 'AllCells'
$dgvTest.ClipboardCopyMode = 'Disable'
$dgvTest.ColumnHeadersHeightSizeMode = 'AutoSize'
$dgvTest.Location = New-Object System.Drawing.Point(22, 43)
$dgvTest.Name = 'dgvTest'
$dgvTest.ReadOnly = $True
$dgvTest.Size = New-Object System.Drawing.Size(240, 315)
$dgvTest.TabIndex = 0

$frmDataGridTest.Add_Shown({GenerateDataGrid})
$dgvTest.SelectionMode = 'FullRowSelect'

$chkAllItems.Add_CheckedChanged({
if($chkAllItems.Checked)
 {
  $dgvTest.SelectAll()
  $Rows = $dgvTest.SelectedRows
  ForEach ($Row in $Rows)
   {
    if($dgvTest.Rows[$Row.Index].Cells['Number'].Value -eq 0)
     {
      $dgvTest.Rows[$Row.Index].Selected = $False
     }
   }
 }
  else
 {
  $dgvTest.ClearSelection()
 }      
})

$btnShow.Add_Click({ShowResults})

[void]$frmDataGridTest.ShowDialog()
[void]$frmDataGridTest.Dispose()

What can I do to make it possible that a user cannot select the rows with the numbers 10, 11 and 13?

Feedback is appreciated a lot.

With kind regards, The Sting Pilot

CodePudding user response:

You were almost there, but you need to handle the grid's SelectionChanged event.

Add this event handler:

$dgvTest.Add_SelectionChanged({
  ForEach ($Row in $dgvTest.SelectedRows){
      $Row.Selected = ($Row.Cells['Number'].Value -ne 0)
  }
})
  • Related