You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell DataGridView根据单元格值禁止选中指定行方法

DataGridView指定行禁止选中实现方案

DataGridView 原生未提供行级的禁选属性:

  • ReadOnly属性仅控制单元格是否可编辑,不影响选中逻辑
  • Locked、Enabled不是DataGridViewRow类的公开有效属性,直接调用会抛出异常
    正确实现逻辑是通过选择状态变更事件拦截,只要检测到Number值为0的行被选中,立刻强制取消其选中状态,可覆盖手动点选、拖拽多选、键盘选择、全选等所有场景。

关键修改点

  • 新增RowStateChanged事件处理,自动拦截禁选行的选中操作
  • 保留原有禁选行灰色背景的提示样式
  • 原有全选复选框逻辑无需大幅修改,事件会自动过滤禁选行
  • 修复原脚本中全局表数据重复累加的小问题

完整可运行代码

Function GenerateDataGrid
{ 
    # 每次生成前清空全局表,避免数据重复累加
    $Global:Table = @()
    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
    # 初始化行样式:给Number=0的行设置灰色背景
    ForEach ($Row in $dgvTest.Rows)
    {
        if($Row.Cells['Number'].Value -eq 0)
        {
            $Row.DefaultCellStyle.BackColor = [System.Drawing.Color]::FromArgb(255, 224, 224, 224)
        }
    }
    $dgvTest.ClearSelection()
}

Function ShowResults
{
    $Rows = $dgvTest.SelectedRows
    Clear-Host
    ForEach ($Row in $Rows)
    {
        $Follow = $Row.Cells['Follow'].Value
        $Number = $Row.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
$dgvTest.SelectionMode = 'FullRowSelect'

# 核心:行状态变更事件,拦截禁选行的选中操作
$dgvTest.Add_RowStateChanged({
    param($sender, $e)
    # 仅处理选中状态变化的行
    if ($e.StateChanged -eq [System.Windows.Forms.DataGridViewElementStates]::Selected) {
        $targetRow = $e.Row
        # 跳过底部新增占位行
        if ($targetRow.IsNewRow) { return }
        # 若为Number=0的禁选行,强制取消选中
        if ($targetRow.Cells['Number'].Value -eq 0) {
            $targetRow.Selected = $false
        }
    }
})

$frmDataGridTest.Add_Shown({GenerateDataGrid})

$chkAllItems.Add_CheckedChanged({
    if($chkAllItems.Checked)
    {
        $dgvTest.SelectAll()
    }
    else
    {
        $dgvTest.ClearSelection()
    }      
})

$btnShow.Add_Click({ShowResults})

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

效果说明

  • 用户手动点击、拖拽多选、按键盘方向键选择时,Number值为0的灰色行始终无法被选中
  • 点击全选复选框时,会自动跳过所有Number值为0的行,仅选中可选项
  • 点击「Show selected items」输出结果时,不会包含任何禁选行数据

内容的提问来源于stack exchange,提问作者TheStingPilot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 19:54:20