来自 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 种方法来实践这个计划。
- 使用无限制的 DGV
- 使用源数据文件
- 虚拟模式 - 在我无法使用 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
之前描述的相同问题将继续存在。绑定源需要 DataSet
、DataTable
或 List<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
我已经测试了这段代码,它似乎可以成功运行。希望对您有所帮助。
我有一个想法来编写一个 PowerShell 脚本来创建带有一些 WF 元素的 GUI,包括 DataGridView 以显示、编辑和存储一些数据(到 $var; @rray;@hash-table/into csv(或另一个)-文件)。
全局我希望它在下一个方案中使用。
PS 创建 GUI 表单,其中 DGV 显示 table 由 3 列组成“#”-数字,"PageName"-页面名称,"shrt"-短页面名称。在第一行中显示默认行值(1、索引、ndx)。
如果用户编辑默认行值 or/-and 创建新行 - 所有更改将自动 接受 1。我看到了 3 种方法来实践这个计划。
- 使用无限制的 DGV
- 使用源数据文件
- 虚拟模式 - 在我无法使用 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
之前描述的相同问题将继续存在。绑定源需要 DataSet
、DataTable
或 List<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
我已经测试了这段代码,它似乎可以成功运行。希望对您有所帮助。