在 PowerShell 中将对象传递给函数时遇到问题

问题描述 投票:0回答:1

这里是新用户。我不从事任何编程/编码工作,并且教育经验有限,所以我所知道的大部分内容都是来自修补。我正在开发一个构建 GUI 的 PowerShell 脚本,但在基于编辑另一个 GUI 项目来更新一个 GUI 项目时遇到了一些问题。我已简化它以显示我遇到的问题。

这是被调用的函数:

function GUITitleTextBox_TextChanged
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$True, Position=0)][System.Object]    $Sender,
        [parameter(Mandatory=$True, Position=1)][System.EventArgs] $EventArguments,
        [parameter(Mandatory=$True, Position=2)][String]           $Text,
        [parameter(Mandatory=$False, Position=3)][System.Object]   $ControlToUpdate
    )
    
    Write-Host $Sender.Text
    Write-Host $Text
    Write-Host $ControlToUpdate.Text
}

这是创建对象并添加事件的相关代码:

#Add the GUI Title textbox
$GUITitleTextBox       = New-Object System.Windows.Forms.TextBox
$GUITitleTextBox.Text  = "Default Form"
$GUITitleTextBox.Width = 240
$GUITitleTextBox.Add_TextChanged({GUITitleTextBox_TextChanged -Sender $this -EventArguments $_ -Text $this.Text -ControlToUpdate $GUITitleTextBox}) #Add an event when text changes.
$Form.Controls.Add($GUITitleTextBox) #Add the textbox to the Form

这是控制台输出:

Default For
Default For

Default Fo
Default Fo

Default F
Default F

使用 $this 传递给函数的任何内容都可以正常工作,如发送数据的两个 Write-Host 命令所示,但是当传递带有变量名称 ($GUITitleTextBox) 的对象时,它不起作用。我可以直接在创建对象的代码下方添加 Write-Host $GUITitletextBox.Text。如果在声明和实例化 $GUITitleTextBox 时我执行 $script:GUITitleTextBox 将范围设置为整个脚本,那么我当然可以更改 Text 属性。

更复杂的是,在不同的脚本上,我可以将 Windows 窗体对象传递给遵循相同格式的函数。

来自其他脚本的函数:

function ContainerDimensionControlChanged()
{
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory=$True, Position=0)] [System.Object] $CallingControl,
        [parameter(Mandatory=$True, Position=1)] [System.Object] $Container,
        [parameter(Mandatory=$True, Position=2)] [string]        $Axis,
        [parameter(Mandatory=$False, Position=3)][System.Object] $ControlToUpdate
    )

    <Removed because it's not relevant>

    $ControlToUpdate.Value = $Container.$Axis
}

这是调用它的代码($Panel 和 $WidthTextBox 都是在运行此代码的同一函数中之前/之后创建的其他表单元素):

$WidthSlider = New-Object System.Windows.Forms.TrackBar
$WidthSlider.Top = 45
$WidthSlider.Left = 330
$WidthSlider.Name = "WidthSlider"
$WidthSlider.AutoSize = $true
$WidthSlider.Minimum = 5
$WidthSlider.Maximum = 750
$WidthSlider.Value = $PanelDefaultWidth
$WidthSlider.Add_ValueChanged({ContainerDimensionControlChanged $This $Panel "Width" $WidthTextBox})

那么为什么第二个有效而第一个无效呢?我错过了什么?

powershell winforms pass-by-reference
1个回答
0
投票

PowerShell 的

$this
变量在事件处理程序的脚本块中使用时并不总是您所期望的。

在您的第一个脚本中,

$this
并不指
$GUITitleTextBox
,而是指脚本块运行的上下文,而不是您的文本框,这就是它无法按预期工作的原因。相反,请使用
$sender
,它会传递给函数并引用引发事件的控件。

这是更正后的事件处理程序添加行:

$GUITitleTextBox.Add_TextChanged({
    GUITitleTextBox_TextChanged -Sender $GUITitleTextBox -EventArguments $_ -Text $GUITitleTextBox.Text -ControlToUpdate $GUITitleTextBox
})
© www.soinside.com 2019 - 2024. All rights reserved.