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

PowerShell WinForm无法获取动态生成TextBox控件数据问题咨询

问题背景

我正在使用PowerShell WinForm开发一款小型预算管理应用,该应用从指定路径下的House.txt文件读取账单列表,根据账单条目在界面动态生成对应的Label、2个TextBox、DateTimePicker(日历)、CheckBox控件并添加到HouseGenPanel容器中,基础功能运行正常。

问题描述

无法从这些动态生成的控件中读取数据,具体需求是将所有“应付款”TextBox的数值累加得到总应付款金额,但遇到以下问题:

  • 绑定的TextBox TextChanged事件无法正确输出对应控件的内容
  • 尝试将TextBox数据存入数组也无法正常读取
  • 尝试监听文本更新事件获取数值也无法实现每个控件的正确更新
原有动态生成控件代码(Generate-Bills函数)
function Generate-Bills
{
    $Due = @() # <- 应付款账单存储数组
    $coord = 40
    foreach ($bill in Get-Content "$path\House.txt") #<- 账单列表存储在该文本文件中
    {
        $BillName  = $bill
        $BillDue   = $bill + "Due"
        $BillNext  = $bill + "Next"
        $BillDate  = $bill + "Date"
        $BillCheck = $bill + "Check"
        
        Write-Host $BillName
        Write-Host $BillDue
        Write-Host $BillNext
        Write-Host $BillDate
        Write-Host $BillCheck
        Write-Host $coord
        
        $BillCheck = New-Object 'System.Windows.Forms.CheckBox'
        $BillDate  = New-Object 'System.Windows.Forms.DateTimePicker'
        $BillNext  = New-Object 'System.Windows.Forms.TextBox'
        $BillDue   = New-Object 'System.Windows.Forms.TextBox'
        $BillName  = New-Object 'System.Windows.Forms.Label'
        #
        # 复选框
        #
        $BillCheck.Left = '478'
        $BillCheck.Top = $coord
        $BillCheck.Name = $BillCheck
        $BillCheck.Size = '104, 24'
        $BillCheck.TabIndex = 4
        $BillCheck.Text = '已支付'
        $BillCheck.ForeColor = $textcolor
        $BillCheck.UseCompatibleTextRendering = $True
        $BillCheck.UseVisualStyleBackColor = $True
        $BillCheck.Anchor = 'Top'
        #
        # 到期日期
        #
        $BillDate.Left = '360'
        $BillDate.Top = $coord
        $BillDate.Name = $BillDate
        $BillDate.Size = '110, 20'
        $BillDate.TabIndex = 3
        $BillDate.Format = 'Short'
        $BillDate.Font = 'Microsoft Sans Serif, 12pt '
        $BillDate.Anchor = 'Top, Bottom'
        #
        # 下期还款
        #
        $BillNext.Left = '238'
        $BillNext.Top = $coord
        $BillNext.Name = $BillNext
        $BillNext.Size = '100, 20'
        $BillNext.TabIndex = 2
        $BillNext.Backcolor = '33, 35, 50'
        $BillNext.BorderStyle = 'None'
        $BillNext.ForeColor = 'White'
        $BillNext.Font = 'Microsoft Sans Serif, 18pt, style=Bold'
        $BillNext.Anchor = 'Top, Bottom'
        #
        # 应付款
        #
        $BillDue.Left = '108'
        $BillDue.Top = $coord
        $BillDue.Name = $BillDue
        $BillDue.Size = '100, 20'
        $BillDue.TabIndex = 1
        $BillDue.Backcolor = '33, 35, 50'
        $BillDue.BorderStyle = 'None'
        $BillDue.ForeColor = 'White'
        $BillDue.Font = 'Microsoft Sans Serif, 18pt, style=Bold'
        $BillDue.Anchor = 'Top, Bottom'
        
    # 失败的尝试
    $BillDue.Add_TextChanged({Write-Host $BillDue.Text})

        #
        # 账单名称
        #
        $BillName.AutoSize = $True
        $BillName.Left = '18'
        $BillName.Top = $coord
        $BillName.Name = $BillName
        $BillName.Size = '35, 17'
        $BillName.TabIndex = 0
        $BillName.Text = $bill
        $BillName.Font = 'Microsoft Sans Serif, 10pt, style=Bold'
        $BillName.ForeColor = 'White'
        $BillName.UseCompatibleTextRendering = $True
        $BillName.Anchor = 'Top, Bottom'
        #
        # 控件添加到容器
        #
        $HouseGenPanel.Controls.Add($BillCheck)
        $HouseGenPanel.Controls.Add($BillDate)
        $HouseGenPanel.Controls.Add($BillNext)
        $HouseGenPanel.Controls.Add($BillDue)
        $HouseGenPanel.Controls.Add($BillName)
        
        $data += $BillDue.Text
        $coord += 50
        $HouseGenPanel.Height += 45
    }
    Write-Host $Due "data"      
}
解决方案

核心逻辑

将容器内的所有控件存入全局变量,后续通过生成控件的.Name属性即可调用对应控件获取其内容。

实现代码

# 将容器控件集合存入全局变量
$global:controls = $HousePanel.controls

# 读取指定控件内容
$output.Text = $global:controls['TextBox1'].text

# 绑定控件文本变更事件
$global:controls['TextBox1'].Add_TextChanged({ $output.Text = $global:controls['TextBox1'].text})

总应付款计算扩展

遍历全局控件集合,筛选出所有名称带Due标识的应付款TextBox,累加其数值即可得到总金额。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:15:03