【问题标题】:powershell add action to comboboxpowershell 向组合框添加操作
【发布时间】:2021-03-12 09:53:00
【问题描述】:

目前,我想构建一个 powershell gui。表格运行良好,所以没有问题。现在我想为我的选择添加一个事件,例如启动另一个脚本选择“item1”和另一个脚本选择“item2”等等。我怎样才能做到这一点?感谢任何帮助。 这就是我实际拥有的。

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Combobox"
$objForm.Size = New-Object System.Drawing.Size(300,200) 
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
 {
     foreach ($objItem in $objCombobox.SelectedItem)
         {$x += $objItem}
     $objForm.Close()
 }
})

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
 {$objForm.Close()}})

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"

$OKButton.Add_Click(
{
     foreach ($objItem in $objCombobox.SelectedItem)
         {$x += $objItem}
     $objForm.Close()
})

$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "please choose"
$objForm.Controls.Add($objLabel) 

$objCombobox = New-Object System.Windows.Forms.Combobox 
$objCombobox.Location = New-Object System.Drawing.Size(10,40) 
$objCombobox.Size = New-Object System.Drawing.Size(260,20) 

[void] $objCombobox.Items.Add("Item 1")
[void] $objCombobox.Items.Add("Item 2")
[void] $objCombobox.Items.Add("Item 3")
[void] $objCombobox.Items.Add("Item 4")
[void] $objCombobox.Items.Add("Item 5")

$objCombobox.Height = 70
$objForm.Controls.Add($objCombobox) 
$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

$x

【问题讨论】:

  • 你为什么要定义$objForm.Add_KeyDown 两次? $x 在这些事件的脚本块中没有任何意义,除非它被定义为具有脚本或全局范围(像 $script:x 一样使用)。将SelectionChanged 事件添加到组合框,您可以在其中对所做的任何选择做出反应。
  • 我不知道 SelectionChanged 代码。在我的代码中看起来如何?能给我一个建议吗?
  • 对不起,我的意思是SelectedIndexChanged

标签: powershell


【解决方案1】:

在修改后的脚本下方继续我的评论

$x =  # the return variable which is updated in the OK Click event
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$objForm               = New-Object System.Windows.Forms.Form
$objForm.Text          = "Combobox"
$objForm.Size          = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview    = $True
$OKButton              = New-Object System.Windows.Forms.Button
$OKButton.Location     = New-Object System.Drawing.Size(75,120)
$OKButton.Size         = New-Object System.Drawing.Size(75,23)
$OKButton.Text         = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$OKButton.Add_Click({
     $script:x = $objCombobox.SelectedItem  # there is only one SelectedItem
     $objForm.Close()
})

$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$objForm.Controls.Add($CancelButton)

# using this, you do not need the Add_KeyDown events to react on clicking the OK or Cancel button
$objForm.AcceptButton = $OKButton
$objForm.CancelButton = $CancelButton

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "please choose"
$objForm.Controls.Add($objLabel) 


$objCombobox = New-Object System.Windows.Forms.Combobox 
$objCombobox.Location = New-Object System.Drawing.Size(10,40) 
$objCombobox.Size = New-Object System.Drawing.Size(260,20) 
$objCombobox.Height = 70

[void] $objCombobox.Items.Add("Item 1")
[void] $objCombobox.Items.Add("Item 2")
[void] $objCombobox.Items.Add("Item 3")
[void] $objCombobox.Items.Add("Item 4")
[void] $objCombobox.Items.Add("Item 5")
$objCombobox.Add_SelectedIndexChanged({
    # for demo, just write to console
    Write-Host "You have selected '$($this.SelectedItem)'" -ForegroundColor Cyan
    # inside here, you can refer to the $objCombobox as $this
    switch ($this.SelectedItem) {
        "Item 1" { <# do something when Item 1 is selected #> }
        "Item 2" { <# do something when Item 2 is selected #> }
        "Item 3" { <# do something when Item 3 is selected #> }
        "Item 4" { <# do something when Item 4 is selected #> }
        "Item 5" { <# do something when Item 5 is selected #> }
    }
})

$objForm.Controls.Add($objCombobox) 
$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

# IMPORTANT clean up the form when done
$objForm.Dispose()

$x

如您所见,我已经删除了两个$objForm.Add_KeyDown() 事件处理程序,因为当您设置$objForm.AcceptButton = $OKButton$objForm.CancelButton = $CancelButton 时不需要它们。此外,使用$objForm.Dispose()

完成后,请始终从内存中删除表单

根据您的评论,我了解您只想在关闭表单后执行所选操作。

在这种情况下,还要删除 $OKButton.Add_Click() 事件处理程序,并将所选选项存储在 SelectedIndexChanged 事件中的 $script:x 中:

$x =  # the return variable which is updated in the SelectedIndexChanged event handler
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$objForm               = New-Object System.Windows.Forms.Form
$objForm.Text          = "Combobox"
$objForm.Size          = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview    = $True
$objForm.Topmost       = $True

$OKButton              = New-Object System.Windows.Forms.Button
$OKButton.Location     = New-Object System.Drawing.Size(75,120)
$OKButton.Size         = New-Object System.Drawing.Size(75,23)
$OKButton.Text         = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$objForm.Controls.Add($OKButton)

$CancelButton              = New-Object System.Windows.Forms.Button
$CancelButton.Location     = New-Object System.Drawing.Size(150,120)
$CancelButton.Size         = New-Object System.Drawing.Size(75,23)
$CancelButton.Text         = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$objForm.Controls.Add($CancelButton)

# using this, you do not need the Add_KeyDown events to react on clicking the OK or Cancel button
$objForm.AcceptButton = $OKButton
$objForm.CancelButton = $CancelButton

$objLabel          = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size     = New-Object System.Drawing.Size(280,20)
$objLabel.Text     = "please choose"
$objForm.Controls.Add($objLabel) 

$objCombobox          = New-Object System.Windows.Forms.Combobox
$objCombobox.Location = New-Object System.Drawing.Size(10,40)
$objCombobox.Size     = New-Object System.Drawing.Size(260,20)
$objCombobox.Height   = 70

[void] $objCombobox.Items.Add("Item 1")
[void] $objCombobox.Items.Add("Item 2")
[void] $objCombobox.Items.Add("Item 3")
[void] $objCombobox.Items.Add("Item 4")
[void] $objCombobox.Items.Add("Item 5")
$objCombobox.Add_SelectedIndexChanged({
    # inside here, you can refer to the $objCombobox as $this
    # set the return variable to the SelectedItem
    $script:x = $this.SelectedItem  # there is only one SelectedItem

    # or, if you want it to, you can start the action here immediately without leaving the form:
    # switch ($this.SelectedItem) {
        # "Item 1" { <# do something when Item 1 is selected #> }
        # "Item 2" { <# do something when Item 2 is selected #> }
        # "Item 3" { <# do something when Item 3 is selected #> }
        # "Item 4" { <# do something when Item 4 is selected #> }
        # "Item 5" { <# do something when Item 5 is selected #> }
    # }
})
$objForm.Controls.Add($objCombobox) 

$objForm.Add_Shown({$objForm.Activate()})
$dialogResult = $objForm.ShowDialog()

# IMPORTANT clean up the form when done
$objForm.Dispose()

if ($dialogResult -eq 'OK' -and ![string]::IsNullOrWhiteSpace($x)) {
    # the form was not cancelled and a selection was made

    # for demo, just write to console
    Write-Host "You have selected '$($x)'" -ForegroundColor Cyan

    switch ($x) {
        "Item 1" { <# do something when Item 1 is selected #> }
        "Item 2" { <# do something when Item 2 is selected #> }
        "Item 3" { <# do something when Item 3 is selected #> }
        "Item 4" { <# do something when Item 4 is selected #> }
        "Item 5" { <# do something when Item 5 is selected #> }
    }
}
else {
    Write-Host "You have cancelled the dialog or did not select anything"
}

好的,显然现在您希望表单在做出选择并单击OK 按钮(并因此执行所选操作)后保持不变。

在这种情况下,您可以这样简化:

$x = @() # the return variable (an array with all selections made in order)
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$objForm               = New-Object System.Windows.Forms.Form
$objForm.Text          = "Combobox"
$objForm.Size          = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview    = $True
$objForm.Topmost       = $True

$OKButton              = New-Object System.Windows.Forms.Button
$OKButton.Location     = New-Object System.Drawing.Size(75,120)
$OKButton.Size         = New-Object System.Drawing.Size(75,23)
$OKButton.Text         = "OK"
$OKButton.Add_Click({ 
    $selected = $objCombobox.SelectedItem
    $script:x += $objCombobox.SelectedItem
    if (![string]::IsNullOrWhiteSpace($selected)) {
        Write-Host "Performing action $($selected)" -ForegroundColor Yellow
        $objLabel.Text = "Performing action $($selected)"
        switch ($selected) {
            "Item 1" { <# do something when Item 1 is selected #> }
            "Item 2" { <# do something when Item 2 is selected #> }
            "Item 3" { <# do something when Item 3 is selected #> }
            "Item 4" { <# do something when Item 4 is selected #> }
            "Item 5" { <# do something when Item 5 is selected #> }
        }
        $objLabel.Text = "Please choose"
        $objCombobox.SelectedIndex = -1   # reset the combobox to blank
    }
})
$objForm.Controls.Add($OKButton)

$CancelButton              = New-Object System.Windows.Forms.Button
$CancelButton.Location     = New-Object System.Drawing.Size(150,120)
$CancelButton.Size         = New-Object System.Drawing.Size(75,23)
$CancelButton.Text         = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$objForm.Controls.Add($CancelButton)

# using this, you do not need the Add_KeyDown events to react on clicking the OK or Cancel button
$objForm.AcceptButton = $OKButton
$objForm.CancelButton = $CancelButton

$objLabel          = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size     = New-Object System.Drawing.Size(280,20)
$objLabel.Text     = "please choose"
$objForm.Controls.Add($objLabel) 

$objCombobox          = New-Object System.Windows.Forms.Combobox
$objCombobox.Location = New-Object System.Drawing.Size(10,40)
$objCombobox.Size     = New-Object System.Drawing.Size(260,20)
$objCombobox.Height   = 70

[void] $objCombobox.Items.Add("Item 1")
[void] $objCombobox.Items.Add("Item 2")
[void] $objCombobox.Items.Add("Item 3")
[void] $objCombobox.Items.Add("Item 4")
[void] $objCombobox.Items.Add("Item 5")

$objForm.Controls.Add($objCombobox) 

$objForm.Add_Shown({$objForm.Activate()})
$dialogResult = $objForm.ShowDialog()

# IMPORTANT clean up the form when done
$objForm.Dispose()

if ($dialogResult -ne 'Cancel' -or $x.Count -eq 0) {
    # the form was cancelled or no selection was made
    # for demo, just write to console
    Write-Host "You have cancelled the dialog or did not select anything.."
}
else {
    Write-Host "The selection(s) you made were $($x -join ', ')" -ForegroundColor Cyan
}

【讨论】:

  • 很好,谢谢。但是我选择的脚本会立即开始,而不是点击确定按钮
  • 效果很好,但如果在选择脚本后表单保持打开状态会很好
  • @chkdsk 好的,我为这个问题添加了最后一段代码。请查看编辑
  • 这也很完美。真的……非常非常感谢。我还有一个问题。请原谅我的许多问题。是否有可能总是重置选择
  • 非常感谢。你是我本周的英雄。效果很好
猜你喜欢
  • 2011-12-10
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多