Winforms 获取父名称

Winforms 获取父名称,winforms,powershell,event-handling,Winforms,Powershell,Event Handling,在本例中,使用什么方法或变量可以找到父对象的名称?也就是说,将鼠标悬停在第一个按钮上时,获取名称$GetParentName=“Button01”,第二个$GetParentName=“Button02”,第三个$GetParentName=“Button03”$GetParentName是[string] 如果不使用变量$GetParentName应用$This,则变量$This允许您获取对象的值,但不获取对象的名称。但是如何获取对象的名称呢?谢谢 编辑:不使用$This.Name 如果要在M

在本例中,使用什么方法或变量可以找到父对象的名称?也就是说,将鼠标悬停在第一个按钮上时,获取名称$GetParentName=
“Button01”
,第二个$GetParentName=
“Button02”
,第三个$GetParentName=
“Button03”
$GetParentName是
[string]

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

编辑:不使用$This.Name


如果要在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对象
循环中创建和命名按钮可以节省键入每个按钮的名称的时间:

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()
正如西奥所指出的,您需要通过指定按钮对象的
.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事件委托

WinForms(正确地)不知道事件源对象存储在PowerShell端的数据结构或变量

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


在本例中,PowerShell本身无法知道您的
$Script
块恰好与哈希表条目中意外存储的按钮实例间接关联。

谢谢。是的,现在我正在做。我把名字写在名字里。然后我使用它
$This.Name
。但这并不总是方便的。我希望有另一种方法。@kааааПаааааааааааа107。我给他加了一个问题。如何在不使用$This.name的情况下查找对象的名称。非常感谢!这是一个普遍的选择。你又一次帮了我。几个小时前,我在想是否可以向对象添加新属性。我在文档中找到了
addmember
。现在,你的例子帮助我通过一个例子来理解这一点。很高兴听到这一点很有帮助,@Каааааааааа。起初我不确定自定义属性是否能够通过.NETAPI保存下来,但它们确实可以,因为PowerShell(自v3以来)一直在尽力保留它们。
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()