获取 parent 个名字

Get parent name

这个例子中parentobject的名字用什么方法或者变量可以查到?也就是说,当鼠标悬停在第一个按钮上时,获取名称 $GetParentName = "Button01",第二个 $GetParentName = "Button02",第三个 $GetParentName = "Button03"。 $GetParentName 是 [string].

如果代替变量$GetParentName应用$This,那么变量$This允许你得到object的值,但不能得到object 的名称。但是如何得到object的名字呢?谢谢

已编辑: 未使用 $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()

如果要在 MouseEnter 脚本中获取按钮控件的名称,则需要为按钮控件设置 .Name 属性:

Add-Type -AssemblyName System.Windows.Forms

$A = @{

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

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

$Script = { Write-host $this.Name }

1..3 | ForEach-Object {

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

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

[void]$A.Main.ShowDialog()

$A.Main.Dispose()


编辑

ForEach-Object 循环中创建和命名按钮可以节省您为每个按钮键入名称的时间:

Add-Type -AssemblyName System.Windows.Forms

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

$Script = { Write-host $this.Name }

1..3 | ForEach-Object {
    $A["Button0$_"] = [System.Windows.Forms.Button] @{ Top = ($_ -1) * 30 ; Name = "Button0$_"}
    $A["Button0$_"].Add_MouseEnter($Script)

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

[void]$A.Main.ShowDialog()

$A.Main.Dispose()

正如 Theo 指出的 ,您需要 通过分配给它们的 .Name 属性.[=22 来命名您的按钮对象=]

避免将按钮命名 两次 - 一次作为哈希表中的 属性 名称,再次通过 .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(扩展类型系统)添加哈希表条目的键,其中每个按钮存储为 a 自定义属性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 作为 .NET 事件委托直接调用WinForms.

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

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

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