L'utilisation d'un formulaire pour renvoyer une variable ne parvient pas à produire une valeur de retour


Adwaenyth

J'écris un script pour un utilisateur qui concatène plusieurs fichiers PDF et ajoute des données tabulaires sous forme de fichier texte. Maintenant, le problème est que l'utilisateur peut nommer manuellement les fichiers texte afin que le script doive vérifier quel fichier PDF appartient aux données. Habituellement, il le ferait par son nom, mais comme l'utilisateur peut (et va évidemment) changer le nom du PDF, le script doit demander à l'utilisateur de choisir le PDF correct à fusionner.

J'ai écrit une fonction dans mon script, qui utilise Winforms pour afficher une liste avec les fichiers PDF disponibles et l'utilisateur doit en choisir un.

function Select-Rechnung
{
    param
    (
        [string] $Rechnung,
        [string[]] $PdfFiles
    )

    $form = New-Object System.Windows.Forms.Form
    $form.Text = "Rechnung wählen"
    $form.Size = New-Object System.Drawing.Size(640,320)
    $form.StartPosition = "CenterScreen"

    $form.KeyPreview = $true
    $form.Add_KeyDown({if($_.KeyCode -eq "Enter") { $x = $PdfFiles[$ListBox.SelectedIndex]; $form.Close() }})
    $form.Add_KeyDown({if($_.KeyCode -eq "Escape") { $form.Close() }})

    $OkButton = New-Object System.Windows.Forms.Button
    $OkButton.Location = New-Object System.Drawing.Size(240,240)
    $OkButton.Size = New-Object System.Drawing.Size(75,23)
    $OkButton.Text = "OK"
    $OkButton.Add_Click({ $x = $PdfFiles[$ListBox.SelectedIndex]; $form.Close() })
    $form.Controls.Add($OkButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(325,240)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Abbrechen"
    $CancelButton.Add_Click({$form.Close()})
    $form.Controls.Add($CancelButton)

    $Label = New-Object System.Windows.Forms.Label
    $Label.Location = New-Object System.Drawing.Size(10,20) 
    $Label.Size = New-Object System.Drawing.Size(600,20) 
    $Label.Text = [string]::Format("Für die Rechnung {0} wurden mehrere mögliche Dateien gefunden. Bitte auswählen:", $Rechnung)
    $form.Controls.Add($Label)

    $ListBox = New-Object System.Windows.Forms.ListBox
    $ListBox.Location = New-Object System.Drawing.Size(10,40)
    $ListBox.Size = New-Object System.Drawing.Size(600, 20)
    $ListBox.Height = 200
    foreach($pdfFile in $PdfFiles)
    {
        [void] $ListBox.Items.Add($pdfFile)
    }
    $form.Controls.Add($ListBox)

    $form.TopMost = $true
    $form.Add_Shown({$form.Activate()})
    [void] $form.ShowDialog()

    $x
}

Désormais, dans le KeyDowngestionnaire ou le Clickgestionnaire, la fonction doit affecter le fichier PDF sélectionné à la variable $x. J'ai vérifié que le $PdfFilessont correctement transmis à la fonction et que lors de l'exécution des gestionnaires, le a $PdfFiles[$ListBox.SelectedIndex]en fait la valeur de chaîne correcte. Cependant, lorsque j'accède $xaprès le ShowDialogtraitement des formulaires , il est vide et donc la valeur de retour de la fonction est vide.

Pourquoi n'assigne-t-il pas la valeur (qu'il évalue correctement pendant le gestionnaire) à ma variable et ne la renvoie-t-elle pas?

Adwaenyth

Je l'ai fait maintenant en contournant le problème. Dans le KeyDownet respectivement le Clickgestionnaire, je ne règle plus la variable directement mais comme:

$form.Add_KeyDown({
    if($_.KeyCode -eq "Enter") 
    { 
         if($ListBox.SelectedIndex -ge 0) 
         { 
             $form.DialogResult = System.Windows.Forms.DialogResult]::OK;
         } 
         $form.Close() 
    }
})

Et à la fin, je vérifie les DialogResult:

[string]$x = $null
if($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK)
{
    $x = $PdfFiles[$ListBox.SelectedIndex]
}   
return $x

Cela a abouti au renvoi de la valeur correcte.

Articles connexes