Как Тео указывает в своем ответе , вам нужно назвать объекты ваших кнопок, присвоив их .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 (Extended Type System), чтобы добавить ключ записи хеш-таблицы, в которой каждая кнопка хранится как 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 не предоставляет и не должен предоставлять автоматическую c (встроенную) переменную например $GetParentName
для поддержки этого сценария:
Существует два несвязанных мира, в которые вовлечено в этом сценарии:
WinForms не зависит от языка c - любой. NET язык может использовать его; все, что он знает, это то, как экземпляры его типов вкладываются во время выполнения и как вызывать соответствующие. NET события, как правило, в ответ на пользовательские события.
исходный объект события как сообщается в WinForms, отображается как $this
в блоке сценария PowerShell, действующем как делегат события. NET, вызываемый непосредственно WinForms.
WinForms (по праву) не знает, какая структура данных или переменная на стороне PowerShell объект, в котором происходит событие, хранится в.
Даже на стороне PowerShell это полностью на ваше усмотрение - вы могли выбрать отдельные переменные, например, или массив, как показано выше, поэтому здесь нет общего шаблона , который может поддерживать автоматическая переменная c.
В данном случае PowerShell сам не может знать, что ваш блок $Script
оказался косвенно связанный с экземпляром кнопки , случайно сохраненным в записи хеш-таблицы .