在这个例子中,我可以用什么方法或变量找出父对象的名称?也就是说,在鼠标悬停在第一个按钮上的事件期间,获取名称 $GetParentName = "Button01" ,第二个 $GetParentName = "Button02" ,第三个 $GetParentName = "Button03" 。 $GetParentName 是 [string]

如果不是变量 $GetParentName 应用 $This ,那么变量 $This 允许您获取对象的值,但不会获取对象的名称。但是如何获取对象的名称呢?谢谢

编辑: 不使用 $This.Name。

$A = @{

    Main = [System.Windows.Forms.Form] @{ StartPosition = 'CenterParent' }

    Button01 = [System.Windows.Forms.Button] @{ Top = 0 }
    Button02 = [System.Windows.Forms.Button] @{ Top = 30 }
    Button03 = [System.Windows.Forms.Button] @{ Top = 60 }
}

$Script = { Write-host $GetParentName }

1..3 | % {

    $A["Button0$_"].Add_MouseEnter($Script)

    $A.Main.Controls.Add($A["Button0$_"])
}

[void]$A.Main.ShowDialog()

最佳答案

正如 Theo 指出的 in his answer ,您需要通过将 .Name 属性分配给 来为按钮对象命名

为避免将按钮命名两次 - 一次作为哈希表中的属性名称,再次通过 .Name 属性 - 您可以 将按钮创建为数组 ,这简化了整体解决方案:

$A = @{

    Main = [System.Windows.Forms.Form] @{ StartPosition = 'CenterParent' }

    # Create an *array* of buttons
    Buttons = [System.Windows.Forms.Button] @{ Top = 0; Name = 'Button1' },
              [System.Windows.Forms.Button] @{ Top = 30; Name = 'Button2' },
              [System.Windows.Forms.Button] @{ Top = 60; Name = 'Button3' }
}

# Print the name of the button being moused over.
$Script = { $this.Name | Out-Host }

# Attach the event-handler script block to each button.
$A.Buttons | % {

    $_.Add_MouseEnter($Script)

}

# Add the buttons to the form.
$A.Main.Controls.AddRange($A.Buttons)

$null = $A.Main.ShowDialog()

如果您想避免分配给 .Name 属性 ,您可以使用以下方法:

使用 PowerShell 的 ETS(扩展类型系统)添加 哈希表条目的键,其中每个按钮存储为 自定义属性 (NoteProperty 实例成员),使用 Add-Member ,事件处理程序脚本可以查询:
Add-Type -AssemblyName System.Windows.Forms

$A = @{

    Main = [System.Windows.Forms.Form] @{ StartPosition = 'CenterParent' }

    Button01 = [System.Windows.Forms.Button] @{ Top = 0 }
    Button02 = [System.Windows.Forms.Button] @{ Top = 30 }
    Button03 = [System.Windows.Forms.Button] @{ Top = 60 }
}

$Script = {
    # Access the custom .CustomParent property added to each button instance below.
    Write-Host $this.CustomParent
}

1..3 | % {

    $key = "Button0$_"
    $btn = $A[$key]
    # Add a .CustomParent NoteProperty member to the button object
    # storing the key of the hashtable entry in which that button is stored.
    $btn | Add-Member -NotePropertyMembers @{ CustomParent = $key }

    $btn.Add_MouseEnter($Script)

    $A.Main.Controls.Add($btn)
}

[void]$A.Main.ShowDialog()

至于为什么 PowerShell 不 - 也不应该 - 提供自动(内置)变量,例如 $GetParentName 来支持这种情况:

这个场景涉及两个不相关的世界:
  • PowerShell 变量
  • System.Windows.Forms 命名空间 (WinForms) 中的 .NET 类型

  • WinForms 与语言无关 - 任何 .NET 语言都可以使用它;它只知道它的类型的实例如何在运行时嵌套以及如何引发适当的 .NET 事件,通常是为了响应用户事件。

    WinForms 报告的事件源对象在 PowerShell 脚本块中显示为 $this,充当 WinForms 直接调用的 .NET 事件委托(delegate)。

    WinForms(理所当然地)不知道事件发起对象存储在 PowerShell 端的数据结构或变量。

    即使在 PowerShell 方面,这也完全由您决定 - 例如,您可以选择单个变量或数组,如上所示,因此这里没有自动变量可以支持的通用模式。

    在手头的情况下,PowerShell 本身无法知道您的 $Script 块恰好与偶然存储在哈希表条目中的按钮实例间接关联。

    关于winforms - 获取 parent 姓名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60226779/

    10-13 09:01