首页 > 解决方案 > 如何在 DataGridView GUI (PowerShell) 中确认数据更改?

问题描述

在我的情况下,我想使用 PS 脚本来构建 WinForm,其中包含一些元素,包括 DGV 包含 3 列(#、Page_Name、shrt)。第一行需要是具有默认值的模板行(1;索引;NDX)所以我从 csv 文件中获取它。
我的代码:

$DataGridView1                    = New-Object system.Windows.Forms.DataGridView
$DataGridView1.location           = New-Object System.Drawing.Point(20,121)
$DataGridView1.Name               = "Page-List"
$DataGridView1.AllowUserToAddRowsChanged = $true
$DataGridView1.AllowUserToAddRows = $true
# $DataGridView1.DataBindings
$DataGridView1.width              = 363
$DataGridView1.height             = 150
$DataGridView1.ColumnCount = 3
$DataGridView1.ColumnHeadersVisible = $true
$DataGridView1.Columns[0].Name = '#'
$DataGridView1.Columns[0].Width = "40"
$DataGridView1.Columns[1].Name = "Page_Name"
$DataGridView1.Columns[1].Width = "205"
$DataGridView1.Columns[2].Name = "shrt"
$DataGridView1.Columns[2].Width = "75"
$DataGridView1.ReadOnly = $false
$DataGridView1.EditMode  = "EditOnEnter"
$templateROW = @(Import-Csv -Delimiter ";"  "C:\Users\vkons\OneDrive\Документы\PowerShell\Scripts\test\DGV\index.csv" -Header "#", "Page_Name", "shrt" )
$datatable = ($templateROW + $DataGridView1Rows)
$DataGridView1Data = $datatable

foreach ($Row in $DataGridView1Data){
    $DataGridView1.Rows.Add($Row.'#', $Row.Page_Name, $Row.shrt)
}

如果用户将更改第一行中的 Page_Name 单元格值或将在下一行(或 rowS)中填充 Page_Name 单元格 - 已编辑行中的“#”列和“shrt”列中的单元格值将通过此程序获取值部分代码:

$DataGridView1.Add_CellValueChanged({autofill})
Function autofill{

$Numbr = $DataGridView1.CurrentRow.Index+1
$DataGridView1.CurrentRow.Cells[0].value = $Numbr

$Name_Page = $DataGridView1.CurrentRow.Cells[1].value
$preshrt = $Name_Page.ToString($Value) -ireplace "[aoueyi]" 
$preshrt = $preshrt.ToUpper()
$shrt = $preshrt[0]+$preshrt[1]+$preshrt[2]
$DataGridView1.CurrentRow.Cells[2].value = $shrt
}

我的主要目标是将列 Page_Name 中所有单元格的值作为变量(或作为数组)。
所以我尝试将下一个字符串添加到上面的函数中。

$Pages = $Row.Page_Name+$DataGridView1.CurrentRow.Cells[1].value

但它什么也不返回......($Row.Page_Name)

我可以通过

$Page_NamesListRows = @($DataGridView1.Rows.Cells.Value)

(不幸的是)它返回变量,由所有现有的单元格组成,而不是行数组。
但是当我尝试

$Page_Names = $DataGridView1.Rows.Cells[1].Value

或者

$Page_Names = $DataGridView1.Columns[1].Cells.Value

要仅获取页面名称,它会返回错误“无法获取空数组的值”(以防 @(...) 用于右侧部分)

有人可以回答...有什么方法可以获取“Page_Name”列中的所有现有单元格。
老实说,是否通过更改单元格值事件来自动编辑 DGVData 并不重要。

我只需要获取列“Page_Name”值。

最后,我想为我的英语道歉。它的水平相当差。并提前感谢版主纠正我的错误。

标签: powershelldatagridviewdatagridviewcolumn

解决方案


恐怕您必须通过遍历“Page_Name”列中的行来获取值数组。
DataGridView 中的最后一行将始终是用户创建的“新”行,因此您需要跳过该行。

通过这样做:

# -1 to skip the always present empty row at the bottom
$Page_Names = for($row = 0; $row -lt $DataGridView1.Rows.Count - 1; $row++) {
    $DataGridView1.Rows[$row].Cells.Item("Page_Name").Value
}

或类似的东西:

$Page_Names = $DataGridView1.Rows | ForEach-Object {
    $data = $_.Cells.Item("Page_Name").Value
    if ($data) { $data }
}

或者:

$Page_Names = foreach ($row in $DataGridView1.Rows) {
    $row.Cells.Item("Page_Name").Value
}
$Page_Names = $Page_Names[0..($Page_Names.Count - 2)]

最后一种方法成本高,因为它需要在删除最后一项时重新创建整个数组

PS1 使用 GUI 完成后,不要忘记调用Dispose()$DataGridview1 对象和主窗体上的方法

PS2 我没有看到AllowUserToAddRowsChanged在 DataGridView 上调用的属性。


编辑

为了更好地展示我的意思,这是一个带有 DataGridView 控件的演示表单。

初始数据来自一个虚拟 CSV 文件,其中包含:

"1";"页码 1";"PN1"
"2";"页码 2";"PN2"
"3";"页码 3";"PN3"
"4";"页码 4";"PN4"
"5";"页码 5";"PN5"
$form            = New-Object System.Windows.Forms.Form
$form.ClientSize = New-Object Drawing.Size 580, 505
$form.text       = "20/4/2020 v. 0.1 All Right reserved (c) "
$form.TopMost    = $true

$DataGridView1                    = New-Object system.Windows.Forms.DataGridView
$DataGridView1.Location           = New-Object System.Drawing.Point 20,25
$DataGridView1.Width              = 363
$DataGridView1.Height             = 150
$DataGridView1.AllowUserToAddRows = $true
$DataGridView1.Name               = "Page-List"
$DataGridView1.ColumnCount        = 3
$DataGridView1.Columns[0].Name    = '#'
$DataGridView1.Columns[0].Width   = "40"
$DataGridView1.Columns[1].Name    = 'Page_Name'
$DataGridView1.Columns[1].Width   = "205"
$DataGridView1.Columns[2].Name    = "shrt"
$DataGridView1.Columns[2].Width   = "75"
$DataGridView1.AllowUserToAddRows = $true
$DataGridView1.ReadOnly           = $false

# Populate the DGV with the data from the CSV
$CsvData = Import-Csv -Path 'D:\Test\TEMPLATE_ROW.csv' -Delimiter ";" -Header "#", "Page_Name", "shrt"
foreach ($row in $CsvData) {
    [void]$DataGridView1.Rows.Add($row.'#', $row.Page_Name, $row.shrt)
}

# add the DGV to the form
$form.Controls.Add($DataGridView1)

# show the form and capture the result so you can check if the user cancelled or pressed OK
$result = $form.ShowDialog()

# at this point, you can read the data from the DataGridView column of interest
$Page_Names = for($row = 0; $row -lt $DataGridView1.Rows.Count - 1; $row++) {
    $DataGridView1.Rows[$row].Cells.Item("Page_Name").Value
}

# cleanup memory by destroying the DGV and the from
$DataGridView1.Dispose()
$form.Dispose()

在变量$Page_Names中,您现在将获得来自 DataGridView 控件中“Page_Name”列的数据。

# show on screen
$Page_Names

推荐阅读