You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复PowerShell脚本使OK按钮显示在自定义对话框标签下方

如何让PowerShell自定义对话框的OK按钮显示在标签下方?

需求是通过PowerShell实现带有大文本、关闭按钮和警报声的自定义对话框,目前已实现对话框显示与警报播放,但OK按钮无法显示在标签下方。用户完全不了解PowerShell,通过ChatGPT 3.5生成的脚本要么无效,要么按钮完全不显示,现有脚本如下:

Add-Type -AssemblyName System.Windows.Forms

# Create a user-defined form class
class CustomMessageBox : System.Windows.Forms.Form {
    CustomMessageBox([string]$title, [string]$message) {
        $this.Text = $title
        $this.ClientSize = New-Object System.Drawing.Size(1500, 400)  # Adjust the form size

        # Show a label with big text
        $label = New-Object System.Windows.Forms.Label
        $label.Text = $message
        $label.Font = New-Object System.Drawing.Font("Arial", 56, [System.Drawing.FontStyle]::Bold)
        $label.TextAlign = [System.Drawing.ContentAlignment]::TopCenter
        $label.Dock = [System.Windows.Forms.DockStyle]::Fill 

        # create an 'OK' button
        $okButton = New-Object System.Windows.Forms.Button
        $okButton.Text = "OK"
        $okButton.Add_Click({
            # Schließe die Form, wenn der OK-Button geklickt wird
            $this.Close()
        })

        $this.Controls.Add($label)
        $this.Controls.Add($okButton)

        # center on the screen
        $this.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    }
}

$title = "Alarm! Dinner is ready."
$popupMessage = "We can now eat dinner, Peter.`nPlease come down."

# Specify the path to your alarm sound file
$alarmSoundPath = "C:\Users\Nils\Documents\Powershell\digital-clock-beep-989.wav"

# Check if the sound file exists
if (Test-Path $alarmSoundPath) {
    # start a background job for playing the alarm
    $alarmJob = Start-Job -ScriptBlock {
        param($path)
        $alarmPlayer = New-Object System.Media.SoundPlayer
        $alarmPlayer.SoundLocation = $path
        while ($true) {
            $alarmPlayer.PlaySync()
        }
    } -ArgumentList $alarmSoundPath

    $customMessageBox = [CustomMessageBox]::new($title, $popupMessage)
    $null = $customMessageBox.ShowDialog()

    # Terminate the background job after closing the MessageBox
    Stop-Job $alarmJob
} else {
    Write-Host "Alarm sound file not found. Please provide a valid path."
}

问题原因

原脚本中Label设置了DockStyle.Fill,会占据整个窗体空间,导致添加的OK按钮被Label完全遮挡,无法显示。

修改方案

使用TableLayoutPanel作为布局容器,将Label和OK按钮分别放在不同的行中,确保两者都能正常显示且布局符合预期。以下是修改后的完整脚本:

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

# 创建自定义窗体类
class CustomMessageBox : System.Windows.Forms.Form {
    CustomMessageBox([string]$title, [string]$message) {
        $this.Text = $title
        $this.ClientSize = New-Object System.Drawing.Size(1500, 400)
        $this.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen

        # 创建布局容器,分为2行1列
        $layoutPanel = New-Object System.Windows.Forms.TableLayoutPanel
        $layoutPanel.Dock = [System.Windows.Forms.DockStyle]::Fill
        $layoutPanel.RowCount = 2
        $layoutPanel.ColumnCount = 1
        # 设置第一行高度自动适应内容,第二行固定高度放置按钮
        $layoutPanel.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::AutoSize)))
        $layoutPanel.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Absolute, 80)))

        # 创建大文本标签
        $label = New-Object System.Windows.Forms.Label
        $label.Text = $message
        $label.Font = New-Object System.Drawing.Font("Arial", 56, [System.Drawing.FontStyle]::Bold)
        $label.TextAlign = [System.Drawing.ContentAlignment]::TopCenter
        $label.AutoSize = $true
        $label.Anchor = [System.Windows.Forms.AnchorStyles]::Top
        # 将标签添加到布局容器第一行
        $layoutPanel.Controls.Add($label, 0, 0)
        $layoutPanel.SetCellPosition($label, (New-Object System.Windows.Forms.TableLayoutPanelCellPosition(0,0)))
        $layoutPanel.SetColumnSpan($label, 1)

        # 创建OK按钮
        $okButton = New-Object System.Windows.Forms.Button
        $okButton.Text = "OK"
        $okButton.Font = New-Object System.Drawing.Font("Arial", 24, [System.Drawing.FontStyle]::Bold)
        $okButton.Size = New-Object System.Drawing.Size(200, 60)
        $okButton.Add_Click({
            $this.Close()
        })
        # 将按钮添加到布局容器第二行,并设置单元格居中对齐
        $layoutPanel.Controls.Add($okButton, 0, 1)
        $layoutPanel.SetCellPosition($okButton, (New-Object System.Windows.Forms.TableLayoutPanelCellPosition(0,1)))
        $layoutPanel.SetColumnSpan($okButton, 1)
        $layoutPanel.SetCellAnchor($okButton, [System.Windows.Forms.AnchorStyles]::Center)

        # 将布局容器添加到窗体
        $this.Controls.Add($layoutPanel)
    }
}

$title = "Alarm! Dinner is ready."
$popupMessage = "We can now eat dinner, Peter.`nPlease come down."

# 警报声音文件路径
$alarmSoundPath = "C:\Users\Nils\Documents\Powershell\digital-clock-beep-989.wav"

if (Test-Path $alarmSoundPath) {
    # 后台播放警报声
    $alarmJob = Start-Job -ScriptBlock {
        param($path)
        $alarmPlayer = New-Object System.Media.SoundPlayer
        $alarmPlayer.SoundLocation = $path
        while ($true) {
            $alarmPlayer.PlaySync()
        }
    } -ArgumentList $alarmSoundPath

    $customMessageBox = [CustomMessageBox]::new($title, $popupMessage)
    $null = $customMessageBox.ShowDialog()

    # 关闭对话框后停止警报
    Stop-Job $alarmJob
} else {
    Write-Host "未找到警报声音文件,请提供有效路径。"
}

关键修改说明

  1. 添加布局容器:使用TableLayoutPanel管理控件布局,避免单个控件占据整个窗体空间
  2. 行样式设置:第一行高度自动适应标签内容,第二行固定高度放置按钮
  3. 控件对齐调整:标签设置顶部对齐,按钮设置单元格居中,确保布局美观
  4. 按钮样式优化:增大按钮字体和尺寸,提升交互体验

内容的提问来源于stack exchange,提问作者Dev4Fun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:19:57