powershell - 如何在 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”值。
最后,我想为我的英语道歉。它的水平相当差。并提前感谢版主纠正我的错误。
解决方案
恐怕您必须通过遍历“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