Динамически создавать EventHandler для динамически создаваемых. NET CheckBox от Powershell - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть скрипт Powershell, который создает форму с панелью:

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$mainForm                        = New-Object system.Windows.Forms.Form
$mainForm.ClientSize             = '450,565'
$mainForm.text                   = "Instalación automatizada de software y componentes"
$mainForm.TopMost                = $False
$mainForm.ShowIcon               = $False

$lblApplications                 = New-Object system.Windows.Forms.Label
$lblApplications.text            = "Aplicaciones"
$lblApplications.AutoSize        = $True
$lblApplications.width           = 25
$lblApplications.height          = 10
$lblApplications.Anchor          = 'top,right,bottom,left'
$lblApplications.location        = New-Object System.Drawing.Point(22,50)
$lblApplications.Font            = 'Microsoft Sans Serif,10'

$pnlApplications                 = New-Object system.Windows.Forms.Panel
$pnlApplications.height          = 125
$pnlApplications.width           = 415
$pnlApplications.Anchor          = 'top,right,bottom,left'
$pnlApplications.AutoScroll      = $True
$pnlApplications.location        = New-Object System.Drawing.Point(17,70)
...

Сценарий динамически добавляет флажки на панель из объекта:

$mainForm.Add_Load({ Initialization-Info; $mainForm.WindowState = [System.Windows.Forms.FormWindowState]::Normal; })

Function Initialization-Info {
    # Fill applications list
    $verticalPosition = 15;
    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        # Add the new Checkbox
        $pnlApplications.controls.AddRange(@($ckbApp))
        $verticalPosition += 23;
    }
}

Мне нужно создать и EventHandler для каждого динамически создаваемого CheckBox, который вызывает функцию, функция должна знать, что CheckBox вызвал EventHandler для выполнения действия.

Я пробовал это без удачи:

OPTION1

    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        $ckbApp.CheckedChanged          += Update-SelectedPackages;
        ...

Function Update-SelectedPackages {
    Write-Output ("Changed checkbox: " + $this.Text);
}

OPTION2

    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        $ckbApp.Add_CheckedChanged({ Update-SelectedPackages })
        ...

Function Update-SelectedPackages {
    Write-Output ("Changed checkbox: " + $this.Text);
}

OPTION3

    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        $ckbApp.Add_CheckedChanged($ckbEventHandler)
        ...

$ckbEventHandler = [System.EventHandler] {
    Write-Output ("Changed checkbox: " + $this.Text);
}

Есть идеи?

РЕДАКТИРОВАТЬ: Спасибо всем, я нашел решение! Вот оно:

Function Initialization-Info {
    # Fill applications list
    $verticalPosition = 15;
    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Type
        $ckbApp.AccessibleDescription   = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        Register-ObjectEvent -InputObject $ckbApp CheckedChanged -Action { Update-SelectedPackages($Sender); }
        ...

Function Update-SelectedPackages ($ckbSender) {
    # Updated Checked state of Chocolatey packages
    If ($ckbSender.Tag -eq "ChocoPkg") {
        If ($pkgToUpdate = $ChocoPackages | Where-Object { $_.Name -eq $ckbSender.AccessibleDescription }) {
            $pkgToUpdate.Checked = $ckbSender.Checked;
        }
    }
    ...

Ответы [ 3 ]

0 голосов
/ 16 апреля 2020

Это должно работать, если вы разрешите параметры для функции Update-SelectedPackages, такие как:

Function Update-SelectedPackages ([string]$boxText, [string]$package) {
    Write-Output "Changed checkbox: $boxText"
    Write-Output "ChocoPackage Name: $package"  # for demo added second parameter
}

, а затем создайте свои флажки как:

Function Initialization-Info {
    # Fill applications list
    $verticalPosition = 15;
    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15, $verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        # add event handler using the values stored in this control
        $ckbApp.Add_CheckedChanged({ Update-SelectedPackages $this.Text $this.Tag })
        # Add the new Checkbox to the panel
        $pnlApplications.Controls.Add($ckbApp)
        $verticalPosition += 23;
    }
}
0 голосов
/ 16 апреля 2020

Решение, которое я нашел:

# Write your logic code here
Function Initialization-Info {
    # Fill applications list
    $verticalPosition = 15;
    ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Type
        $ckbApp.AccessibleDescription   = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'
        Register-ObjectEvent -InputObject $ckbApp CheckedChanged -Action { Update-SelectedPackages($Sender); }
        ...

Function Update-SelectedPackages ($ckbSender) {
    # Updated Checked state of Chocolatey packages
    If ($ckbSender.Tag -eq "ChocoPkg") {
        If ($pkgToUpdate = $ChocoPackages | Where-Object { $_.Name -eq $ckbSender.AccessibleDescription }) {
            $pkgToUpdate.Checked = $ckbSender.Checked;
        }
    }
    ...
0 голосов
/ 16 апреля 2020

Я действительно столкнулся с этой проблемой несколько недель go при создании формы для обслуживания сетевой системы. Вы действительно близки к исправлению, но есть одна вещь, которую нужно изменить. Поскольку функция Update-SelectedPackages является внешней функцией (фактически не связанной с флажком), вы должны передать ей объект-бокс в качестве параметра. Надеюсь, это поможет!

ForEach ($ChocoPkg In $ChocoPackages) {
        $ckbApp                         = New-Object system.Windows.Forms.CheckBox
        $ckbApp.Text                    = $ChocoPkg.Desc
        $ckbApp.Tag                     = $ChocoPkg.Name
        $ckbApp.AutoSize                = $False
        $ckbApp.Width                   = 380
        $ckbApp.Height                  = 20
        $ckbApp.Location                = New-Object System.Drawing.Point(15,$verticalPosition)
        $ckbApp.Font                    = 'Microsoft Sans Serif,10'

        # add a click function to the checkbox to be executed when clicked
        $ckbApp.CheckedChanged.add_click({
            Update-SelectedPackages($this)
        })
        ...

# pass $box element into the method so that the text can be referenced
Function Update-SelectedPackages($box) {
    Write-Output ("Changed checkbox: " + $box.Text);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...