在这个例子中,我可以用什么方法或变量找出父对象的名称?也就是说,在鼠标悬停在第一个按钮上的事件期间,获取名称 $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
来支持这种情况:
这个场景涉及两个不相关的世界: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/