winforms 如何为动态添加到Powershell中WinForm的按钮创建单独的事件处理程序

n1bvdmb6  于 2023-04-21  发布在  Shell
关注(0)|答案(1)|浏览(234)

我试图有一个动态创建的WinForm,在那里我传递了一个字典的名称(键)和网址的图像托管(值)。
代码循环遍历字典并为每个“键”添加一个按钮,当按钮被按下时,它将picturebox设置为该按钮的url处的图像。
每次可以有不同数量的按钮(可能最多10个)。
我不知道我的方法(下图)是否正确,但我得到了我想要的大部分。问题是,无论按下哪个按钮,图像都是'梅森'。

Add-Type -AssemblyName System.Windows.Forms

# Define a dictionary of names and image URLs
$image_url_lookup = @{
    'Eric' = 'https://cdn.images.express.co.uk/img/dynamic/67/285x190/1758705_1.jpg'
    'Mason' = 'https://cdn.images.express.co.uk/img/dynamic/67/285x190/1758732_1.jpg'
    'Other' = 'https://cdn.images.express.co.uk/img/dynamic/67/285x190/1758699_1.jpg'
}

# Create a new form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Select Images"
$form.Width = 800
$form.Height = 600
$form.BackColor = [System.Drawing.Color]::White

# Create a new table layout panel
$tableLayoutPanel = New-Object System.Windows.Forms.TableLayoutPanel
$tableLayoutPanel.Dock = [System.Windows.Forms.DockStyle]::Fill

# Create a new picture box
$pictureBox = New-Object System.Windows.Forms.PictureBox
$pictureBox.Width = $form.Width - 100
$pictureBox.Height = $form.Height - 100
$pictureBox.Left = ($form.Width - $pictureBox.Width) / 2
$pictureBox.Top = ($form.Height - $pictureBox.Height) / 2
$pictureBox.BackColor = [System.Drawing.Color]::Transparent
$pictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::Zoom

$image_index = 0

foreach ($name in $image_url_lookup.Keys) {
    $image_index++
    $button = New-Object System.Windows.Forms.Button
    $button.Name = "Button$image_index"
    $button.Text = $name
    $button.AccessibleName = $image_url_lookup[$name]
    $button.Add_Click({ $pictureBox.ImageLocation = $button.AccessibleName })
    $button.Width = 75
    $button.Height = 23
    
    # Add the button to the table layout panel
    $tableLayoutPanel.Controls.Add($button, $i, 0)
}

# Add the picture box to the table layout panel
$tableLayoutPanel.Controls.Add($pictureBox, 0, 1)
$tableLayoutPanel.SetColumnSpan($pictureBox, $image_index + 5)

# Add the table layout panel to the form
$form.Controls.Add($tableLayoutPanel)

# Show the form
$form.ShowDialog() | Out-Null
$form.Dispose()
nnt7mjpx

nnt7mjpx1#

你需要在你的循环中添加一个.GetNewClosure() call,这样每个脚本块在被赋值时 * 记住 * $button.AccessibleName是什么,否则你总是得到最后创建的$button的值:

foreach ($name in $image_url_lookup.Keys) {
    $image_index++
    $button = [System.Windows.Forms.Button]@{
        Name           = "Button$image_index"
        Text           = $name
        AccessibleName = $image_url_lookup[$name]
        Width          = 75
        Height         = 23
    }
    $button.Add_Click({ $pictureBox.ImageLocation = $button.AccessibleName }.GetNewClosure())
    $tableLayoutPanel.Controls.Add($button, $i, 0)
}

更好的方法是在事件中使用$this自动变量,这样就不需要新的闭包;Theo在他的评论中暗示了这一点:

foreach ($name in $image_url_lookup.Keys) {
    $image_index++
    $button = [System.Windows.Forms.Button]@{
        Name           = "Button$image_index"
        Text           = $name
        AccessibleName = $image_url_lookup[$name]
        Width          = 75
        Height         = 23
    }
    $button.Add_Click({ $pictureBox.ImageLocation = $this.AccessibleName })
    $tableLayoutPanel.Controls.Add($button, $i, 0)
}

相关问题