基于Forms + Panels的Powershell GUI - 更新时闪烁

时间:2015-12-22 23:09:49

标签: powershell

在我们开始之前,让我放在一边:我对Powershell并不熟悉。凭借在虚拟机环境和Googlefu中的实验,我知道的不仅仅是我周围的人,这就是为什么它落在了我身上。

这是我的问题。我创建了一个小型Powershell GUI。我已经构建了一个表单,并以这种形式嵌入了四个面板。 IndexPanel,ScreenSelectionPanel,OptionsPanel和ThemePanel。

表单本身有一个'OK'和'CANCEL'按钮。 每个面板都有一个NEXT,PREVIOUS或两个按钮,具体取决于位置。 ScreenSelect只有NEXT 选项有NEXT和PREVIOUS 主题有上一个

索引以相同的形式浮动到一侧,让你跳转,因为稍后会有更多的面板。

我已经达到了可以让面板 - 大小相同 - 通过单独命名的按钮上的add_click调用从一个滑动到下一个面板的程度,我的面板功能一次性调用所有面板调用的参数。例如,如果参数为'1',则SelectScreen调用方法.show(),而其他调用方法.hide()。

前几次点击,效果很好。我的问题是,来回点击三四次后,应用程序开始闪烁。然后开始滞后。然后开始做两件事。我怀疑问题是在处理paint的方式,因为我所说的只是'刷新'或'更新'。

有没有人找到一种在Powershell中以单一形式从面板切换到面板的顺畅方式?是的,我意识到VB甚至C都是一个更好的解决方案,因为我更倾向于推动Powershell应该处理的事情,但是这些都不是通过项目的性质可用的。它必须在Powershell中完成,并支持.NET。

示例代码,因为我的当前是一堆乱七八糟的提醒和哈希我写的错误。一旦我记下我撞到的路障,我就会把它全部清理干净。我将所有变量加载到脚本的顶部,以便在调用它们的每个函数的范围内考虑它们。它还可以帮助我跟踪我所拥有的所有变量,所以不要担心我在这里没有加载。另外,我省略了方框,按钮等的定义 - 如果它对问题的范围很重要,我会添加它。只是为了减少这么多垃圾邮件。

function GUIPanels {
    function ScreenSelectPanel{
        $objScreenSelectPanel.Size = New-Object System.Drawing.Size(500,600)
        $objScreenSelectPanel.BorderStyle = "FixedSingle"
        $objScreenSelectPanel.AutoScroll = "True"
        $objScreenSelectPanel.AutoSize = "True"
        $objScreenSelectPanel.Width = 400

        if ($Args[0] -eq 1) {$objScreenSelectPanel.Show()}
        else {$objScreenSelectPanel.Hide()}

        $SelectionPanelNEXTButton.Add_Click({
                GUIPanels 2
                $objMainForm.Update()
        })
    }
    function OptionsPanel {
        $objOptionsPanel.Size = New-Object System.Drawing.Size(500,600)
        $objOptionsPanel.BorderStyle = "FixedSingle"
        $objOptionsPanel.AutoScroll = "True"
        $objOptionsPanel.AutoSize = "True"
        $objOptionsPanel.Width = 400

        if ($Args[0] -eq 2) {$objOptionsPanel.Show()}
        else {$objOptionsPanel.Hide()}

        $OptionsPanelNEXTButton.Add_Click({
             GUIPanels 3
             $objMainForm.Update()
        })

        $OptionsPanelPREVIOUSButton.Add_Click({
            GUIPanels 1
            $objMainform.Update()
        })
    }
    function ThemePanel {
        $objThemePanel.Size = New-Object System.Drawing.Size(500,600)
        $objThemePanel.BorderStyle = "FixedSingle"
        $objThemePanel.AutoScroll = "True"
        $objThemePanel.AutoSize = "True"
        $objThemePanel.Width = 400

        if ($Args[0] -eq 3) {$objThemePanel.Show()}
        else {$objThemePanel.Hide()}

        $ThemePanelPREVIOUSButton.Add_Click({
            GUIPanels 1
            $objMainform.Update()
        })
    }
}

function GUIMainForm {
    $objMainForm.Size = New-Object System.Drawing.Size(680,700)
    $objMainForm.AutoScroll = "True"
    $objMainForm.KeyPreview = $True
    #Location setups.
    $objMainForm.StartPosition = "CenterScreen"
    #Key captures. Adding in activity for button presses.
    #Letting panels handle the ENTER Key for now.
    #$objMainForm.Add_KeyDown({
    #   if ($_.KeyCode -eq "Enter") {
    #       $x=$objMainScreenBox.SelectedItem
    #       $objMainForm.Close()
    #       }
    #   })
    $objMainForm.Add_KeyDown({
        if ($_.KeyCode -eq "Escape") {
            $objMainForm.Close()
            }
        })

    #Button Locations.
    $OKButton.Location = New-Object System.Drawing.Size(175,620)
    $CloseButton.Location = New-Object System.Drawing.Size(320,620)

    #Panel Locations.
    $objScreenSelectPanel.Location = New-Object System.Drawing.Size(220,10)
    $objOptionsPanel.Location = New-Object System.Drawing.Size(220,10)
    $objThemePanel.Location = New-Object System.Drawing.Size(220,10)
    $objIndexPanel.Location = New-Object System.Drawing.Size(10,10)


    $objMainForm.Controls.add($objIndexPanel)
    $objMainForm.Controls.add($objScreenSelectPanel)
    $objMainForm.Controls.add($objThemePanel)
    $objMainForm.Controls.add($objOptionsPanel)

    $objMainForm.Controls.add($OKButton)
    $objMainForm.Controls.add($CloseButton)

    $objMainForm.Topmost = $True

    #$objMainForm.DoubleBuffered = "True"
    }

function GUISetup {

    #1 - main screen, 2 - optionals, 3 - theme, 4 - Slipdata

    #for ($i=1; $i -le 4; $i++) {Write-Host  (4%$i)} -- Doesn't feed $i properly.
    GUIBoxes
    GUIButtons
    GUILabels
    GUIMainForm
    GUIPanels $Args[0]

    #$objMainForm.Add_Shown({$objMainForm.Activate()})
    #[void] $objMainForm.ShowDialog()
    #$objMainForm.hide()
    #timeout 5 > $null
    #$objMainForm.show()
    #timeout 4 > $null


    #$objMainForm.Update()
    #$objMainForm.hide()
    #$objMainForm.Refresh()


    #$InitialFormWindowState = $objMainForm.WindowState
    #Init the OnLoad event to correct the initial state of the form
    #$objMainForm.add_Load($Form_StateCorrection_Load)

    #Handling Refresh in the actual button press.   
    return $objMainForm.ShowDialog()
    #$objMainForm.Dispose()
    #$objApplicationClass.run($objMainForm)
    }

#DEBUG
GUIsetup 1 | Out-Null
$x

1 个答案:

答案 0 :(得分:0)

我实际上弄清楚我做错了什么。也就是说,我会调用每个面板来创建每个下一个或上一个。因此,四个面板,八个面板,十二个面板,十六个面板(闪烁),二十个面板(闪烁闪烁减慢)等等。我非常关注这是Powershell的问题,我没有停下来思考我正在使用的逻辑。

所以我要在一个单独的函数中调用.hide()和.show()。