将类中对象的事件处理程序连接到同一类中的方法

时间:2019-04-24 03:14:02

标签: powershell

我编写了一个小类,其中包含几个Windows.Forms对象。我想将一些代码附加到关闭窗体的$ 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似乎仅限于按钮本身,但我希望能够回到课堂上。

是否可以将事件处理程序指向类中的方法,从而获取类中的所有对象?

2 个答案:

答案 0 :(得分: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.Form属性的.Close方法,因为它很简单。如果需要,我可以轻松地从实例中调用方法。

答案 1 :(得分:0)

您可以将param($sender,$e)添加到事件处理程序中以接收这些对象。这将允许您访问处理程序内的$ sender(您的按钮)。然后,您可以调用FindForm()来查找包含按钮的表单。小心.Parent,因为它是直接父对象,如果您有任何面板等,则它可能是与顶层表单不同的对象。

    # 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()
    }
}