#powershell
#powershell
Вопрос:
Я закодировал небольшой класс, который имеет несколько окон.Формирует в нем объекты. Я хочу прикрепить некоторый код к обработчику события кнопки $Cancel, который закрывает форму. Работает приведенный ниже код:
Class MyObject
{
$Form = (New-Object System.Windows.Forms.Form)
$DataGridView = (New-Object System.Windows.Forms.DataGridView)
$Cancel = (New-Object System.Windows.Forms.Button)
$Save = (New-Object System.Windows.Forms.Button)
# Setup all my controls here and add them to $Form...
$this.AddEventHandlers()
}
hidden [void] AddEventHandlers ()
{
# Closes form.
$this.Cancel.Add_Click( { $this.Parent.Close() } )
}
Первоначально я попытался подключить код события к методу объекта в моем классе ( $this.Form.Close()
), но, похоже, возникла проблема с контекстом, и код обработчика событий, казалось, ничего не знал о моем классе. Когда я изменил его на $this.Parent.Close()
, он начал работать. $this
Кажется, что область действия обработчика событий ограничена самой кнопкой, но я хочу иметь возможность вернуться к своему классу.
Есть ли способ, которым я могу указать обработчику событий на метод в моем классе и, следовательно, получить доступ ко всем объектам в моем классе?
Ответ №1:
На случай, если это кого-нибудь заинтересует, я нашел решение.
Чтобы у меня всегда была ссылка на экземпляр моего объекта, из которого происходит обработка событий, я добавил член (свойство) к каждому объекту, который я хочу убедиться, что может взаимодействовать с экземпляром и передавать ссылку на экземпляр. Итак, для кнопки отмены я сделал это:
Class MyObject
{
$Form = (New-Object System.Windows.Forms.Form)
$DataGridView = (New-Object System.Windows.Forms.DataGridView)
$Cancel = (New-Object System.Windows.Forms.Button)
$Save = (New-Object System.Windows.Forms.Button)
# Setup all my controls here and add them to $Form...
# Add property new property and set it to a reference to $this instance.
Add-Member -InputObject $this.Cancel -MemberType NoteProperty -Name MyObject -Value $this
$this.AddEventHandlers()
}
hidden [void] AddEventHandlers ()
{
# Closes form; now we have all methods and objects from instance at our disposal.
$this.Cancel.Add_Click( { $this.MyObject.Form.Close() } )
}
С помощью .Свойство MyObject теперь выходит из кнопки, я могу вызвать метод из класса для выполнения работы. В этом случае я решил просто вызвать .Закройте метод с помощью $this.MyObject.Свойство формы, как это было прямолинейно. Я мог бы так же легко вызвать метод из моего экземпляра, если бы это было необходимо.
Ответ №2:
Вы можете добавить param($sender,$e)
в свой обработчик событий, чтобы получать эти объекты. Это позволит вам получить доступ к $sender (вашей кнопке) внутри обработчика. Затем вы можете вызвать FindForm(), чтобы найти форму, содержащую кнопку. Осторожно с .Родитель, поскольку это непосредственный родитель, который может быть объектом, отличным от формы верхнего уровня, если у вас есть какие-либо панели и т.д.
# Closes form.
$this.Cancel.Add_Click( {
param($sender, $e)
$form = $sender.FindForm()
if($null -ne $form){
$form.Close()
}
} )
Если вы хотите настроить методы в своем классе, вы также можете это сделать, хотя я когда-либо мог использовать только статические методы для этого. Это добавляет проблему, связанную только с возможностью доступа к статическим свойствам и методам.
#Will error when called, cannot call instance value from static
static [void] CloseMe(){
$form.Close()
}
#removing static isn't better as it will now error here
#method cannot be found
$button.Add_MouseClick({
CloseMe($this, $_)
})
#but you can use statics
$button.Add_MouseClick({
[MyObject]::CloseMe($this, $_)
})
#will work though its essentially the same as placing it all in the handler
static [void] CloseMe($sender, $e){
$f = $sender.FindForm()
if($null -ne $f){
$f.Close()
}
}
Комментарии:
1. Спасибо за ваш вклад и предостережения. Однако мой важный вопрос остается без ответа: возможно ли подключить обработчик событий к методу в моем классе? Я не просто пытаюсь настроить таргетинг на форму, я хочу вернуться к самому классу; похоже, у меня все еще будет та же проблема здесь. Или я что-то упускаю? Спасибо.
2. Чтобы добраться до самого инкапсулирующего класса, я думаю, вам придется использовать статические свойства или методы. Форма передается обработчику событий, поэтому мы можем получить к нему доступ, но я не могу найти способ добраться до инкапсулирующего класса.
3. Спасибо за ваш вклад. Я на самом деле выяснил, по крайней мере, один способ сделать это. Смотрите ответ, который я отправил.