TreeView对象的SelectedNode 属性 挂窗体多线程
SelectedNode Property Of TreeView Object Hangs The Form Multithreading
我正在编写 GUI 脚本,但 运行 我遇到了 TreeView 对象的问题。当我尝试显示 SelectedNode 属性 或尝试使用在另一个线程中显示的 TreeView 的 GetNodeAt() 方法时,会出现问题。不过,我能够显示 TreeView 对象本身。这是我正在尝试做的示例:
$form = new-object system.windows.forms.form
$treeview = new-object system.windows.forms.treeview
$treeview.name = "tree view"
$treeview.add_afterselect({write-host $this.selectednode})
$treenode = new-object system.windows.forms.treenode
$treenode.name = "tree node"
$treenode.text = "tree node"
$treenode2 = new-object system.windows.forms.treenode
$treenode2.name = "second tree node"
$treenode2.text = "second tree node"
$treeview.nodes.addrange(@($treenode,$treenode2))
$form.controls.add($treeview)
$thread = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$thread.Open()
$thread.SessionStateProxy.SetVariable("form",$form)
$thepipe = $thread.CreatePipeline({$form.Showdialog()})
$thepipe.Input.Close()
$thepipe.InvokeAsync()
问题出现在行 $treeview.add_afterselect({write-host $this.selectednode})
当我单击树视图中的一个节点时,表单将挂起,我必须终止 Powershell 进程。奇怪的是我可以毫无问题地显示 TreeView 对象。像这样:$treeview.add_afterselect({write-host $this})
。这将 return TreeView 对象没有问题。我也尝试过使用它 $treeview.add_nodemouseclick({write-host $this.getnodeat($_.x,$_.y)})
。这样也会挂表格。
问题出在另一个线程中显示的表单,因为当我执行相同的代码但将表单保留在同一线程中时,显示所选节点没有问题。像这样:
$form = new-object system.windows.forms.form
$treeview = new-object system.windows.forms.treeview
$treeview.name = "tree view"
$treeview.add_afterselect({write-host $this.selectednode})
$treenode = new-object system.windows.forms.treenode
$treenode.name = "tree node"
$treenode.text = "tree node"
$treenode2 = new-object system.windows.forms.treenode
$treenode2.name = "second tree node"
$treenode2.text = "second tree node"
$treeview.nodes.addrange(@($treenode,$treenode2))
$form.controls.add($treeview)
$form.Showdialog()
任何帮助将不胜感激。谢谢!
如果您查看 TreeViewEventHandler
方法签名,您会发现它有两个参数,一个 sender
和一个 TreeViewEventArgs
对象。
您可以通过声明自己的命名参数来 "intercept" 这些,如下所示:
$treeview.add_AfterSelect({
param($s,$e)
# $e now refers to the TreeViewEventArgs
Write-Host $e.Node
})
或者您可以依赖自动事件变量 $Sender
和 $EventArgs
:
$treeview.add_AfterSelect({
Write-Host $EventArgs.Node
})
您可能需要查看 Register-ObjectEvent
and about_Automatic_Variables
的帮助文件
不要在事件操作中使用 $this
- 它旨在用作脚本方法定义中的实例引用,如下所示:
PS C:\> $obj = New-Object psobject -Property @{ Number = 3 }
PS C:\> $obj |Add-Member -Type ScriptMethod -Name GetSquare -Value { return $this.Number * $this.Number }
PS C:\> $obj.GetSquare()
9
PS C:\> $obj.Number = 4
PS C:\> $obj.GetSquare()
16
我正在编写 GUI 脚本,但 运行 我遇到了 TreeView 对象的问题。当我尝试显示 SelectedNode 属性 或尝试使用在另一个线程中显示的 TreeView 的 GetNodeAt() 方法时,会出现问题。不过,我能够显示 TreeView 对象本身。这是我正在尝试做的示例:
$form = new-object system.windows.forms.form
$treeview = new-object system.windows.forms.treeview
$treeview.name = "tree view"
$treeview.add_afterselect({write-host $this.selectednode})
$treenode = new-object system.windows.forms.treenode
$treenode.name = "tree node"
$treenode.text = "tree node"
$treenode2 = new-object system.windows.forms.treenode
$treenode2.name = "second tree node"
$treenode2.text = "second tree node"
$treeview.nodes.addrange(@($treenode,$treenode2))
$form.controls.add($treeview)
$thread = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$thread.Open()
$thread.SessionStateProxy.SetVariable("form",$form)
$thepipe = $thread.CreatePipeline({$form.Showdialog()})
$thepipe.Input.Close()
$thepipe.InvokeAsync()
问题出现在行 $treeview.add_afterselect({write-host $this.selectednode})
当我单击树视图中的一个节点时,表单将挂起,我必须终止 Powershell 进程。奇怪的是我可以毫无问题地显示 TreeView 对象。像这样:$treeview.add_afterselect({write-host $this})
。这将 return TreeView 对象没有问题。我也尝试过使用它 $treeview.add_nodemouseclick({write-host $this.getnodeat($_.x,$_.y)})
。这样也会挂表格。
问题出在另一个线程中显示的表单,因为当我执行相同的代码但将表单保留在同一线程中时,显示所选节点没有问题。像这样:
$form = new-object system.windows.forms.form
$treeview = new-object system.windows.forms.treeview
$treeview.name = "tree view"
$treeview.add_afterselect({write-host $this.selectednode})
$treenode = new-object system.windows.forms.treenode
$treenode.name = "tree node"
$treenode.text = "tree node"
$treenode2 = new-object system.windows.forms.treenode
$treenode2.name = "second tree node"
$treenode2.text = "second tree node"
$treeview.nodes.addrange(@($treenode,$treenode2))
$form.controls.add($treeview)
$form.Showdialog()
任何帮助将不胜感激。谢谢!
如果您查看 TreeViewEventHandler
方法签名,您会发现它有两个参数,一个 sender
和一个 TreeViewEventArgs
对象。
您可以通过声明自己的命名参数来 "intercept" 这些,如下所示:
$treeview.add_AfterSelect({
param($s,$e)
# $e now refers to the TreeViewEventArgs
Write-Host $e.Node
})
或者您可以依赖自动事件变量 $Sender
和 $EventArgs
:
$treeview.add_AfterSelect({
Write-Host $EventArgs.Node
})
您可能需要查看 Register-ObjectEvent
and about_Automatic_Variables
不要在事件操作中使用 $this
- 它旨在用作脚本方法定义中的实例引用,如下所示:
PS C:\> $obj = New-Object psobject -Property @{ Number = 3 }
PS C:\> $obj |Add-Member -Type ScriptMethod -Name GetSquare -Value { return $this.Number * $this.Number }
PS C:\> $obj.GetSquare()
9
PS C:\> $obj.Number = 4
PS C:\> $obj.GetSquare()
16