Подключение обработчика событий объекта в классе к методу в том же классе

#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. Спасибо за ваш вклад. Я на самом деле выяснил, по крайней мере, один способ сделать это. Смотрите ответ, который я отправил.