Winforms 父项如何在System.Windows.Forms中工作

Winforms 父项如何在System.Windows.Forms中工作,winforms,powershell,Winforms,Powershell,我有以下代码()按预期工作: Add-Type -AssemblyName System.Windows.Forms class MyForm : System.Windows.Forms.Form { MyForm($mystuff) { #Do-Stuff $this.Add_Load( $this.MyForm_Load ) } $MyForm_Load = { $mlabel = [System.Windows.

我有以下代码()按预期工作:

Add-Type -AssemblyName System.Windows.Forms

class MyForm : System.Windows.Forms.Form {
    MyForm($mystuff) {
        #Do-Stuff
        $this.Add_Load( $this.MyForm_Load )
    }

    $MyForm_Load = {
        $mlabel = [System.Windows.Forms.Label]::new()
            $mlabel.Name = "label"
            $mlabel.Text = "disabled"

        $mbutton = [System.Windows.Forms.Button]::new()
            $mbutton.Name = "button"
            $mbutton.Location = [System.Drawing.Point]::new(100,100)
            $mbutton.Add_Click( $this.mbutton_click )

        $this.Controls.Add($mlabel)
        $this.Controls.Add($mbutton)

    # ----------------------------------------------
    # Now $this.controls has something. We can now access it.
    # ----------------------------------------------
        if ($this.controls["label"].text -eq "enabled"){
            $mbutton.text = "disable"
        }else{
            $mbutton.text = "enable"
        }
    }

    $mbutton_click = {
        if ($this.Parent.Controls["label"].Text -eq "enabled"){
            $this.Parent.Controls["label"].Text = "disabled"
            $this.Parent.Controls["button"].Text = "enable"
        }
        else{
            $this.Parent.Controls["label"].Text = "enabled"
            $this.Parent.Controls["button"].Text = "disable"
        }
    }
}

$foo = [MyForm]::new("test")
$foo.ShowDialog()
但当我替换以下部分时:

$mbutton_click = {
    if ($this.Parent.Controls["label"].Text -eq "enabled"){
        $this.Parent.Controls["label"].Text = "disabled"
        $this.Parent.Controls["button"].Text = "enable"
    }
    else{
        $this.Parent.Controls["label"].Text = "enabled"
        $this.Parent.Controls["button"].Text = "disable"
    }
}
对于此(缺少父项):

然后我的脚本停止工作,我在控制台上看到以下错误:

The property 'Text' cannot be found on this object. Verify that the property exists and can be set.

为什么
$MyForm\u Load
在没有
父项的情况下工作,但是
$mbutton\u单击
需要
父项
$MyForm\u Load
$mbutton\u click
不是同一个对象的一部分吗?
Parent
如何在
System.Windows.Forms
中工作

这是因为在事件处理程序中,$this
绑定到事件的发送者(本例中的按钮),而不是类实例。因此,类似的方法也应该有效:

$mbutton_click = {
    if ($this.Text -ne "enable") {
        $this.Parent.Controls["label"].Text = "disabled"
        $this.Text = "enable"
    }
    else{
        $this.Parent.Controls["label"].Text = "enabled"
        $this.Text = "disable"
    }
}

这是因为在事件处理程序中,$this
被绑定到事件的发送者(本例中的按钮),而不是类实例。因此,类似的方法也应该有效:

$mbutton_click = {
    if ($this.Text -ne "enable") {
        $this.Parent.Controls["label"].Text = "disabled"
        $this.Text = "enable"
    }
    else{
        $this.Parent.Controls["label"].Text = "enabled"
        $this.Text = "disable"
    }
}

正如@mhu所说,这是因为与单个控件对象相比,一个控件绑定到表单加载事件

表单就是一个类。这意味着表格具有:

属性

属性是类中可引用的对象。它们可以是简单的字符串,如
.Name
,也可以是复杂的字符串,如
.Controls
,返回复杂的
控件.ControlCollection
对象

方法:

调用方法调用编译时完全定义的单个函数定义。调用方法,例如
MyForm.ShowDialog()
调用单个
.ShowDialog()
函数

事件:

有时我们想做一些事情,但不能在编译时完全定义方法调用。但是,与此同时,我们非常喜欢调用定义为方法的东西的便利性。这是可以使用事件的地方

首先。我们想到了一个方法调用,用于我们希望发生的有用的事情,比如
MyForm.Load()
,这就是我们在编译时必须定义的全部内容。现在我们不知道我们想做什么。我们知道我们希望能够加载表单,但我们不知道它会做什么或看起来像什么。所以我们把它作为一个占位符,我们可以调用它

经过一番思考,我们找到了我们想要做的事情,以及我们想要的东西是什么样子的,然后我们构建了一个功能来做一些有用的事情。然后,我们将此函数订阅到一个事件。这就像连接它一样

在第一种情况下:

MyForm($mystuff) {
    $this.Add_Load( $this.MyForm_Load )
}
我们正在将
MyForm\u Load
注册到
MyForm.Load
事件中:

MyForm.Load -> MyForm_Load
这意味着当我们调用
MyForm.Load()
时,它将调用我们编写的连接函数
MyForm\u Load
,并将执行它,就像我们在编译时将其作为一个实际方法编写一样

因此,在
MyForm\u Load
中,
$this
指的是
MyForm
表单对象。i、 e.不需要
.parent
,因为您是表单的

因此,要访问
MyForm.Controls
属性,您可以直接访问它

MyForm.Load -> MyForm_Load
MyForm.Controls
第二点:

$MyForm_Load = {
    $mlabel = [System.Windows.Forms.Label]::new()
        $mlabel.Name = "label"
        $mlabel.Text = "disabled"

    $mbutton = [System.Windows.Forms.Button]::new()
        $mbutton.Name = "button"
        $mbutton.Location = [System.Drawing.Point]::new(100,100)
        $mbutton.Add_Click( $this.mbutton_click )

    $this.Controls.Add($mlabel)
    $this.Controls.Add($mbutton)
}
控件
添加到
窗体。控件
对象:

MyForm.Load -> MyForm_Load
MyForm.Controls 
           |-> mlabel  
           |-> mbutton
mbutton
控件附加了一个单击事件:

$MyForm_Load = {
...
    $mbutton.Add_Click( $this.mbutton_click )
...
}

$mbutton_click = {
...
        $this.Parent.Controls["label"].Text = "disabled"
...
}
所以现在看起来像:

MyForm.Load -> MyForm_Load
MyForm.Controls
           |-> mlabel.Text
           |-> mbutton.Click -> mbutton_click
因此,从
MyForm\u Load
mlabel.Text
是:

 $this  .Controls["label"] .Text 
(MyForm).Controls[(mlabel)].Text
mbutton\u单击
,则
mbutton
中没有任何控件。您必须“向上”窗体一级才能获得
mlabel
控件:

 $this   .Parent  .Controls["label"] .Text 
(mbutton).(MyForm).Controls[(mlabel)].Text

正如@mhu所说,这是因为与单个控件对象相比,一个控件绑定到表单加载事件

表单就是一个类。这意味着表格具有:

属性

属性是类中可引用的对象。它们可以是简单的字符串,如
.Name
,也可以是复杂的字符串,如
.Controls
,返回复杂的
控件.ControlCollection
对象

方法:

调用方法调用编译时完全定义的单个函数定义。调用方法,例如
MyForm.ShowDialog()
调用单个
.ShowDialog()
函数

事件:

有时我们想做一些事情,但不能在编译时完全定义方法调用。但是,与此同时,我们非常喜欢调用定义为方法的东西的便利性。这是可以使用事件的地方

首先。我们想到了一个方法调用,用于我们希望发生的有用的事情,比如
MyForm.Load()
,这就是我们在编译时必须定义的全部内容。现在我们不知道我们想做什么。我们知道我们希望能够加载表单,但我们不知道它会做什么或看起来像什么。所以我们把它作为一个占位符,我们可以调用它

经过一番思考,我们找到了我们想要做的事情,以及我们想要的东西是什么样子的,然后我们构建了一个功能来做一些有用的事情。然后,我们将此函数订阅到一个事件。这就像连接它一样

在第一种情况下:

MyForm($mystuff) {
    $this.Add_Load( $this.MyForm_Load )
}
我们正在将
MyForm\u Load
注册到
MyForm.Load
事件中:

MyForm.Load -> MyForm_Load
这意味着当我们调用
MyForm.Load()
时,它将调用我们编写的连接函数
MyForm\u Load
,并将执行它,就像我们在编译时将其作为一个实际方法编写一样

因此,在
MyForm\u Load
中,
$this
指的是
MyForm
表单对象。i、 e.不需要
.parent
,因为您是表单的

因此,要访问
MyForm.Controls
属性,您可以直接访问它

MyForm.Load -> MyForm_Load
MyForm.Controls
第二点:

$MyForm_Load = {
    $mlabel = [System.Windows.Forms.Label]::new()
        $mlabel.Name = "label"
        $mlabel.Text = "disabled"

    $mbutton = [System.Windows.Forms.Button]::new()
        $mbutton.Name = "button"
        $mbutton.Location = [System.Drawing.Point]::new(100,100)
        $mbutton.Add_Click( $this.mbutton_click )

    $this.Controls.Add($mlabel)
    $this.Controls.Add($mbutton)
}
控件
添加到
窗体。控件
对象:

MyForm.Load -> MyForm_Load
MyForm.Controls 
           |-> mlabel  
           |-> mbutton
mbutton