System.Windows.Form 在按下按钮时不填充变量

问题描述 投票:0回答:1

如果选择了按钮,下面的 PS 不会填充变量。但是,如果选择按键 1-2,则选择打印机。

该按钮适用于语言选择的按钮选择,但不适用于打印机选择。按键 1-2 正在工作。一旦通过 $_.打印机名称在框中选择了打印机,就不会填充 $global:printerChoice 的变量。里面是空的。

Add-Type -AssemblyName "System.Windows.Forms"

# Initialize global variables
$language = 0
$printerChoice = ""

# Language Selection Form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select Language'
$form.Size = New-Object System.Drawing.Size(300, 200)
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen  # Center the form
$form.TopMost = $true  # Keep the form in the foreground
$form.KeyPreview = $true  # Ensure the form captures key presses

# Create a label for instructions
$label = New-Object System.Windows.Forms.Label
$label.Text = 'Select your language (1: English, 2: Español):'
$label.Location = New-Object System.Drawing.Point(10, 10)
$label.Size = New-Object System.Drawing.Size(280, 40)
$form.Controls.Add($label)

# Create buttons for each language
$buttonEnglish = New-Object System.Windows.Forms.Button
$buttonEnglish.Text = "1. English"
$buttonEnglish.Location = New-Object System.Drawing.Point(10, 60)
$buttonEnglish.Size = New-Object System.Drawing.Size(260, 40)
$buttonEnglish.Add_Click({
    $global:language = 1
    Write-Host "Language selected: English (1)"
    $form.Close()
})
$form.Controls.Add($buttonEnglish)

$buttonSpanish = New-Object System.Windows.Forms.Button
$buttonSpanish.Text = "2. Español"
$buttonSpanish.Location = New-Object System.Drawing.Point(10, 110)
$buttonSpanish.Size = New-Object System.Drawing.Size(260, 40)
$buttonSpanish.Add_Click({
    $global:language = 2
    Write-Host "Language selected: Español (2)"
    $form.Close()
})
$form.Controls.Add($buttonSpanish)

# KeyDown event for capturing keyboard and numpad inputs
$form.Add_KeyDown({
    $key = $_.KeyCode
    Write-Host "Key pressed: $key"

    if ($key -eq [System.Windows.Forms.Keys]::D1 -or $key -eq [System.Windows.Forms.Keys]::NumPad1) {
        $global:language = 1
        Write-Host "Language selected: English (1)"
        $form.Close()
    } elseif ($key -eq [System.Windows.Forms.Keys]::D2 -or $key -eq [System.Windows.Forms.Keys]::NumPad2) {
        $global:language = 2
        Write-Host "Language selected: Español (2)"
        $form.Close()
    }
})

# Show the form for language selection
$form.ShowDialog()

# Output the selected language for debugging
Write-Host "Selected Language: $global:language"

# Set language messages based on selection
if ($global:language -eq 2) {
    $langMessage = @{
        "choosePrinter" = "Seleccione su impresora desde la lista."
        "setDefault" = "La impresora predeterminada ha sido configurada."
        "orientationLandscape" = "La orientación de la impresora está en horizontal."
        "orientationNotLandscape" = "La orientación de la impresora no está en horizontal. Comuníquese con el supervisor coordinador o con el departamento de TI para configurarla."
        "noPrinterSelected" = "No se seleccionó ninguna impresora. Seleccione una impresora predeterminada para sus facturas."
        "printerError" = "Error al obtener información de la impresora. Verifique la impresora seleccionada."
        "methodInvocationError" = "Hubo un error al configurar la impresora predeterminada."
        "orientationError" = "Error al verificar la orientación de la impresora."
    }
} else {
    $langMessage = @{
        "choosePrinter" = "Please choose your printer from the list."
        "setDefault" = "The default printer has been set."
        "orientationLandscape" = "The printer orientation is in Landscape."
        "orientationNotLandscape" = "The printer orientation is not in Landscape. Contact Supervisor Coordinator or IT to set the printer orientation."
        "noPrinterSelected" = "No printer selected. Please Select a default printer for your invoices."
        "printerError" = "Error getting printer information. Please check the selected printer."
        "methodInvocationError" = "There was an error setting the default printer."
        "orientationError" = "Error checking printer orientation."
    }
}

# Fetch the list of printers
$printers = Get-Printer | Select-Object Name
$printersCount = $printers.Count
Write-Host "Printers found: $printersCount"

# Create the form for printer selection
$printerForm = New-Object System.Windows.Forms.Form
$printerForm.Text = $langMessage["choosePrinter"]
$printerForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen  # Center the form
$printerForm.TopMost = $true  # Keep the form in the foreground

# Calculate the size of the printer form based on the number of printers
$buttonHeight = 40
$padding = 20
$formHeight = $printersCount * ($buttonHeight + $padding) + 100  # Add extra space for form controls
$printerForm.Size = New-Object System.Drawing.Size(300, $formHeight)
$printerForm.KeyPreview = $true  # Ensure the form captures key presses

# Create buttons for each printer
$buttons = @()
$yOffset = 60
$printers | ForEach-Object -Begin {
    $yOffset = 60  # Start position for the first button
} -Process {
    Write-Host "Creating button for printer: $($_.Name)"  # Debugging message to check printer name
    $button = New-Object System.Windows.Forms.Button
    $button.Text = "$($printers.IndexOf($_) + 1). $($_.Name)"
    $button.Location = New-Object System.Drawing.Point(10, $yOffset)
    $button.Size = New-Object System.Drawing.Size(260, $buttonHeight)
    $button.Add_Click({
        Write-Host "Button clicked for printer: $($_.Name)"  # Debugging button click
        $global:printerChoice = $_.Name
        Write-Host "Printer selected: $global:printerChoice"  # Verify the selection
        $printerForm.Close()
    })
    $printerForm.Controls.Add($button)
    $yOffset += $buttonHeight + $padding  # Increase Y position for next button
    $buttons += $button
}

# KeyDown event for capturing keyboard and numpad inputs for printer selection
$printerForm.Add_KeyDown({
    $key = $_.KeyCode
    Write-Host "Key pressed for printer selection: $key"
    $index = -1

    # Check for number key press
    if ($key -ge [System.Windows.Forms.Keys]::D1 -and $key -le [System.Windows.Forms.Keys]::D9) {
        $index = $key - [System.Windows.Forms.Keys]::D1
    } elseif ($key -ge [System.Windows.Forms.Keys]::NumPad1 -and $key -le [System.Windows.Forms.Keys]::NumPad9) {
        $index = $key - [System.Windows.Forms.Keys]::NumPad1
    }

    if ($index -ge 0 -and $index -lt $printersCount) {
        Write-Host "Selected printer from key press: $($printers[$index].Name)"  # Debugging key press
        $global:printerChoice = $printers[$index].Name
        $printerForm.Close()
    }
})

# Show the printer selection form
$printerForm.ShowDialog()

# Output the selected printer for debugging
Write-Host "Selected Printer: $global:printerChoice"

# Proceed with printer selection if valid choice is made
if (-not $printerChoice) {
    [System.Windows.Forms.MessageBox]::Show($langMessage["noPrinterSelected"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
    return
}

# Set the printer as the default
try {
    Write-Host "Attempting to set $global:printerChoice as default printer."
    $Printer = Get-CimInstance -Class Win32_Printer -Filter "Name='$global:printerChoice'"
    if (-not $Printer) {
        Write-Host "Error: Printer not found."
        [System.Windows.Forms.MessageBox]::Show($langMessage["printerError"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
        return
    }
    Invoke-CimMethod -InputObject $Printer -MethodName SetDefaultPrinter | Out-Null
    Write-Host "Default printer set to: $global:printerChoice"
    [System.Windows.Forms.MessageBox]::Show("$global:printerChoice $($langMessage['setDefault'])", "Success", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
} catch {
    Write-Host "Error setting default printer: $_"
    [System.Windows.Forms.MessageBox]::Show($langMessage["methodInvocationError"], "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
}

调试输出:

选择语言:英语(1)

取消

选择的语言:1

找到打印机:5

为打印机创建按钮:Snagit 2024

为打印机创建按钮:OneNote for Windows 10

为打印机创建按钮:PDF Writer - bioPDF

为打印机创建按钮:OneNote(桌面)

为打印机创建按钮:HP LaserJet Pro M402-M403 n-dne PCL 6

单击打印机按钮:

选择的打印机:

取消

所选打印机:

好的

powershell forms variables
1个回答
0
投票

正如所评论的,在像

Add_Click({..})
这样的事件处理程序中,
$_
自动变量不是您正在迭代的打印机,而是处理程序的EventArgs。 在 Add-Click() 事件处理程序中,这将是一个描述鼠标单击本身的对象(位置、左键或右键等)

为了将打印机名称与相应的按钮很好地保持在一起,我建议将此打印机名称存储在按钮自己的

.Tag
属性中:

尝试:

$printers = Get-Printer | Select-Object -ExpandProperty Name  # just the name. for short use (Get-Printer).Name

# Create buttons for each printer
$buttonHeight = 40
$padding      = 20
$yOffset      = 60 # Start position for the first button
$index        = 1  # for the button text

# your code does not show any reason for collecting the buttons in a variable $buttons, but
# if you do need it, collect the array like below and do not use $buttons += $button
$buttons = $printers | ForEach-Object {
    Write-Host "Creating button for printer: $_"  # Debugging message to check printer name
    $button          = [System.Windows.Forms.Button]::new()
    $button.Text     = '{0}. {1}' -f $index++, $_
    $button.Tag      = $_                         # store the printer name in the .Tag property
    $button.Location = [System.Drawing.Point]::new(10, $yOffset)
    $button.Size     = [System.Drawing.Size]::new(260, $buttonHeight)
    $button.Add_Click({
        # now, the button has the actual printername in its .Tag property
        $printerName = $this.Tag  # for convenience
        Write-Host "Button clicked for printer: $printerName"  # Debugging button click
        $global:printerChoice = $printerName                   # try $script: scope instead
        Write-Host "Printer selected: $global:printerChoice"   # Verify the selection
        $printerForm.Close()
    })
    $printerForm.Controls.Add($button)
    $yOffset += $buttonHeight + $padding  # Increase Y position for next button
    $button                               # output the new object to be captured in variable $buttons
}

我在这里使用新语法来定义 System.Drawing 对象。当然,

New-Object ..
也可以,不过这样应该会快一点。不过,您需要 PowerShell 版本 5 及更高版本

© www.soinside.com 2019 - 2024. All rights reserved.