来自 CSV(或其他来源)的 GridViewData 绑定源

GridViewData Binding source from CSV (or other sorce)

我有一个想法来编写一个 PowerShell 脚本来创建带有一些 WF 元素的 GUI,包括 DataGridView 以显示、编辑和存储一些数据(到 $var; @rray;@hash-table/into csv(或另一个)-文件)。

全局我希望它在下一个方案中使用。

PS 创建 GUI 表单,其中 DGV 显示 table 由 3 列组成“#”-数字,"PageName"-页面名称,"shrt"-短页面名称。在第一行中显示默认行值(1、索引、ndx)。

如果用户编辑默认行值 or/-and 创建新行 - 所有更改将自动 接受 1。我看到了 3 种方法来实践这个计划。

  1. 使用无限制的 DGV
  2. 使用源数据文件
  3. 虚拟模式 - 在我无法使用 1 和 2 模式之前不考虑。

我的代码的通用部分

$DataGridView1                    = New-Object      system.Windows.Forms.DataGridView
$DataGridView1.location           = New-Object System.Drawing.Point(20,21)
$DataGridView1.Name               = "Page-List"
$DataGridView1.AllowUserToAddRowsChanged
$DataGridView1.AllowUserToAddRows
$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 = 'PageName'
$DataGridView1.Columns[1].Width = "205"
$DataGridView1.Columns[2].Name = "shrt"
$DataGridView1.Columns[2].Width = "75"
$DataGridView1.ReadOnly = $false
$DataGridView1.EditMode  = "EditOnEnter"
foreach ($Row in $DataGridView1Data){
  $DataGridView1.Rows.Add($Row)
}

1st. 使用 unbounded DGV

在这种情况下更改之前的 DGVData 具有此值

$DataGridView1Data = @(@($CurrentRow.index+1, "index", "ndx")) #default Row

 $DataGridView1Data = @(@("1", "index", "ndx"),@(" "," "," "))

没关系(除了第二种情况下的 +1 空字符串)。

所以在这种情况下 "accept1" 意味着 declare/edit variable/array/hash-table。

我 运行 遇到了 2 个问题,其中的值是最新的步骤。

问题 #1:

我无法理解为现有行的已编辑单元格更新 $DataGridView1Data 数组值的命令过程。

没有发生任何事情
$DataGridView1.Add_CellEndEdit({savechanges})
function savechanges {
    $DataGridView1.CurrentCellDirtyStateChanged
}

问题 #2

我不明白如何获取新的行值数组。我认为这些过程需要部分代码修改

foreach ($Row in $DataGridView1Data){
  $DataGridView1.Rows.Add($Row)
}

我尝试过的一些 googoleplex 变体

 foreach ($row in $DataGridView1Data){
     [ordered]@{ 
         $DataGridView.Columns[0].Name = $cell[0].Value ;
           $DataGridView.Columns[1].Name = $cell[1].Value ;
            $DataGridView.Columns[2].Name = $cell [3].Value;}
 }

$DataGridView1Data.Add_CellValueChanged({Bind-Pages})
 function Bind-Pages {
     Foreach ($DataGridView1.Row in $DataGridView1RowCollection){
     $DataGridView1.Row = @{id = $cell[0].text; name = $cell[1].text; shrt = $cell[2].text}
}

{$DataGridView1.Row = @($Cell[0].Value, $Cell[1].Value, $Cell[2].Value)}

顺便说一句,“$CurrentRow.Index+1”总是return“1”,不管它的实际值如何。$DGV.RowCount总是return是“1”。但是 $Row[i] - returns 所有存在的正确数组 Rows.This 是最奇怪的。

我认为这两个问题都需要为新行和事件 okbutton click 添加一些代码条目。

我的问题:

如何获取数组或 hash-tables 具有已编辑行的更新值? (包括我添加的。)或为所有 DGVData 更新 hash-table。

我不要求您为 ME.COULD 编写完整代码,您只需告诉我一个算法或给我 LINK 手册。请不要这样 $H[ i ] +

我阅读 docs.ms 长达 2 周,绝对没有什么比这更容易理解了...包括因为我不懂 C#.. 我安装了 MS Office、SQL、PowerShell Studio。 .但我仍然找不到任何解决方案

2nd. 使用 bounded DGV

这样 accepted1 对我来说意味着更新源文件中的数据或将新值导出到其他文件。不重要。

但是 export/update 我无法比源绑定阶段更接近。

我创建了 CSV:https://yadi.sk/i/RDwpL37TNwROgg 截图

并尝试了这个:

$x =  @(Import-Csv -Delimiter ";"  "C:\Users\vkons\OneDrive\Документы\PowerShell\Scripts\SANDBOXES\WEB\resourses\CSV\DATA1.csv"  -Header "#", "Page_Name", "shrt" )
   $DataGridView1Data = @($x)

第一列单元格值受 hash-tables 行约束{All columnsNameS =All cellvalueS in this row}。首先我认为是因为我的 csv 内容格式错误(没有 header)。不可能。但什么都没有

https://yadi.sk/i/umWT6EnwDkmg0Q-截图

如果试试这个

$DataGridView1.Row[0] = $x[0]

return错误

InvalidOperation: Cannot index into a null array.

我做了另一个 googolplex 不同的尝试,使用“.DataSource”属性 将数据绑定到 DGV; DGV数据; DGV.Rows; DGVRowCollection。一切正常。

所以,我的第二个问题:

你能给我写一个绑定源文件数据的算法吗?

这个问题很宽泛,不清楚你“具体”问的是什么。根据您的评论……“请告诉我一个算法”……这实际上是不可能的。没有一种算法可以适用于所有情况。如果没有具体细节,可能会出现“通用”算法,但它仍然缺乏具体细节,具体细节会根据使用它的上下文而有所不同。

对于初学者,我只是猜测您必须为此使用 PowerShell,或者 PowerShell 是您最熟悉的。这绝对可以在 PowerShell 中完成,但是根据您编写代码的环境,使用 PowerShell 恕我直言会使这变得更加困难。

我只是说恕我直言,使用像 Visual Studio 和 C# 或 VB 这样的 IDE 会容易得多。我猜可能还有其他选择,但是帮助解决错误的 IDE 将是至关重要的,而且根据我有限的 PowerShell 经验,解决错误的帮助几乎不存在。我并不是要劝阻您使用 PowerShell,我的意见显然是基于非 PowerShell 用户。我只是说我不经常使用 PowerShell,而且我很难尝试使用 PowerShell 来提供帮助。

放下我的肥皂盒,我可以说,在尝试将数据源绑定到网格时,我发现有几件事可能会给您带来一些问题。

首先,在“2nd.使用有界 DGV。” Header部分,有两行代码…

$x =  @(Import-Csv -Delimiter ";"  "C:\Users\vkons\OneDrive\Документы\PowerShell\Scripts\SANDBOXES\WEB\resourses\CSV\DATA1.csv"  -Header "#", "Page_Name", "shrt" )
$DataGridView1Data = @($x)

据我所知,在这些行成功执行后,变量 $DataGridView1Data 是一个 Object[] 数组。 $DataGridView1Data中的每个item/element也是一个Object。具体来说。似乎每个项目都是 System.Management.Automation.PSCusomObject 类型。我不否认这个“自定义”对象包含简单字段(#、PageName、shrt),但是,网格和绑定源在使用这些“通用对象”解析这些属性时会遇到问题。我不知道这是“为什么”,只能通过我的测试来验证,下面 foreach 循环遍历所有 $DataGridView1Data 行的代码行……将失败……

$DataGridView1.Rows.Add($Row)

网格不会将各个值解析到单独的列中。这是将行直接添加到已有列的网格中。即使设置每列的 DataPropertyName 也未能正确显示数据。

幸运的是,由于 $DataGridView1Data 对象数组确实具有我们需要的值,因此在将行添加到网格时,手动解析每行的值似乎可行……

$DataGridView1.Rows.Add($Row.'#', $Row.Page_Name, $Row.shrt)

接下来您似乎想使用 BindingSource。使用 BindingSource 之前描述的相同问题将继续存在。绑定源需要 DataSetDataTableList<T> 等。同样,它不会解析出 Object。因此,如果要使用BindingSource,则需要将数据转换为合适的数据源。在这种情况下,下面的示例为此使用 DataTable

类似于遍历 $DataGridView1Data 对象并将行直接添加到网格,我们使用相同的循环并将行添加到 DataTable。然后我们可以将此 DataTable 本身用作网格的数据源,或者我们可以将其用作 BindingSource 的数据源。两种方式都可以,在下面的示例中引入了 BindingSource

首先创建一个 DataTable 并添加三 (3) 列。然后通过数据循环将行添加到 table。接下来 table 用作 BindingSource 的数据源,最后将网格数据源设置为 BindingSource.

$GridDT = New-Object system.Data.DataTable
$col = New-Object System.Data.DataColumn(“#”)
$GridDT.Columns.Add($col)
$col = New-Object System.Data.DataColumn(“Page_Name”)
$GridDT.Columns.Add($col)
$col = New-Object System.Data.DataColumn(“shrt")
$GridDT.Columns.Add($col)

# add rows to the DataTable
foreach ($Row in $DataGridView1Data){
  $GridDT.Rows.Add($Row.'#', $Row.Page_Name, $Row.shrt)
}
# use the DataTable as a data source to the binding source
$DataGridViewBS = New-Object system.Windows.Forms.BindingSource
$DataGridViewBS.DataSource = $GridDT
$DataGridView1.DataSource = $DataGridViewBS

我已经测试了这段代码,它似乎可以成功运行。希望对您有所帮助。