问题描述
尝试在 PowerShell 中创建简单的 win 表单。会有一些自动计算的复选框,我正在为尺寸而苦苦挣扎 - 似乎“AutoSize”是一个废话*t,并且返回的值无处不在。任何人都可以请帮助并建议您如何创建动态定位?基于哪些值?
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$nrOfNIC = 2
$nrOfdisks = 3
$nrOfPIP = 1
$vShift = 20
$allChkb = 1
$chkForm = New-Object system.Windows.Forms.Form
$chkForm.text = "Remove Resources"
$chkForm.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$chkForm.AutoSize = $true
$chkForm.StartPosition = 'CenterScreen'
$chkForm.FormBorderStyle = 'Fixed3D'
$chkForm.Icon = [System.Drawing.SystemIcons]::Question
$chkForm.Topmost = $true
$chkForm.MaximizeBox = $false
$chkVMBox = new-object System.Windows.Forms.GroupBox
#$chkVMBox.MinimumSize = New-Object System.Drawing.Size(180,100)
$chkVMBox.AutoSize = $true
$chkVMBox.Location = New-Object System.Drawing.Point(10,10)
$chkVMBox.Text = 'VM resources'
#$chkVMBox.Anchor = 'left,top'
#$lastControl = $chkVMBox
if($nrOfdisks -gt 0) {
$chkVMdisks = new-object System.Windows.Forms.GroupBox
#$chkVMdisks.MinimumSize = New-Object System.Drawing.Size(180,20)
$chkVMdisks.Location = New-Object System.Drawing.Point(10,20)
$chkVMdisks.Text = 'disKs'
#$chkVMdisks.Anchor = 'left,top'
for($disk=0;$disk -lt $nrOfdisks;$disk++) {
$chkbdisk = New-Object System.Windows.Forms.CheckBox
$chkbdisk.Location = New-Object System.Drawing.Point(10,($vShift+($disk*$vShift)) )
#$chkbdisk.Anchor = 'left,top'
$chkbdisk.AutoSize = $true
$chkbdisk.Text = "disk $disk"
$chkbdisk.TabIndex = $allChkb++
$chkVMdisks.Controls.Add($chkbdisk)
#$allChkb++
}
$chkVMBox.Controls.Add($chkVMdisks)
#$lastControl=$chkVMdisks
}
if($nrOfNIC -gt 0) {
#$vLocation = $lastControl.Bottom+$shift
$vLocation = $chkVMdisks.Bottom+$shift
$chkVMNICs = new-object System.Windows.Forms.GroupBox
#$chkVMNICs.MinimumSize = New-Object System.Drawing.Size(180,20)
$chkVMNICs.AutoSize = $true
$chkVMNICs.Location = New-Object System.Drawing.Point(10,$vLocation)
$chkVMNICs.Text = 'NICs'
#$chkVMNICs.Anchor = 'left,top'
for($nic = 0;$nic -lt $nrOfNIC; $nic++) {
$chkbNIC = New-Object System.Windows.Forms.CheckBox
$chkbNIC.Location = New-Object System.Drawing.Point(10,($vShift+($nic*$vShift)) )
#$chkbNIC.Anchor = 'left,top'
$chkbNIC.AutoSize = $true
$chkbNIC.Text = "nic $nic"
$chkbNIC.TabIndex = $allChkb++
$chkVMNICs.Controls.Add($chkbNIC)
#$allChkb++
}
$chkVMBox.Controls.Add($chkVMNICs)
#$lastControl = $chkVMNICs
}
#$vLocation = $lastControl.Bottom+$shift
$vLocation = $chkVMNICs.Bottom+$shift
$chkbVMdiag = New-Object System.Windows.Forms.CheckBox
$chkbVMdiag.Location = New-Object System.Drawing.Point(10,$vLocation)
#$chkbVMdiag.Anchor = 'left,top'
$chkbVMdiag.AutoSize = $true
$chkbVMdiag.Text = "Boot Diagnostics"
$chkbVMdiag.TabIndex = $allChkb++
$chkVMBox.Controls.Add($chkbVMdiag)
$vLocation = $chkVMBox.bottom + 40
$btOK = New-Object System.Windows.Forms.Button
$btOK.Location = New-Object System.Drawing.Size(15,$vLocation)
$btOK.Size = New-Object System.Drawing.Size(70,20)
$btOK.Text = "OK"
$btOK.DialogResult = [System.Windows.Forms.DialogResult]::OK
#$btOK.Anchor = 'left,bottom'
$btCancel = New-Object System.Windows.Forms.Button
$btCancel.Location = New-Object System.Drawing.Size(95,$vLocation)
$btCancel.Size = New-Object System.Drawing.Size(70,20)
$btCancel.Text = "Cancel"
$btCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
#$btCancel.Anchor = 'right,bottom'
$chkForm.AcceptButton = $btOK
$chkForm.CancelButton = $btCancel
$chkForm.Controls.AddRange(@($chkVMBox,$btOK,$btCancel))
[void]$chkForm.ShowDialog()
- 主窗体的右侧有一些大的填充
- 在复选框列表中 - 第一个控件中有额外的空间,第二个控件中有两倍的空间
- 最后一个 chkBox 下有一些填充
- chkVMBox(主框)返回 'size = 100' 'bottom = 110' 并且使用此值的按钮实际上在其他控件下并且不可见。
似乎 ALL VALUES 与 'autosize' 一起返回的都是废话*t。那么您如何创建动态布局,而无需预先知道元素的大小/数量?
解决方法
- 主窗体右侧有一些大的填充
- 在复选框列表中 - 第一个控件有额外的空间,第二个控件的空间翻倍
- 最后一个chkbox下有一些填充
设置 .AutoSizeMode = 'GrowAndShrink'
和 .MinimumSize
属性以及 .AutoSize
。
- 按钮……实际上在其他控件之下并且不可见
按钮位置源自$chkVMBox.bottom
;使用 $chkForm.Controls.Add($chkVMBox)
before 计算按钮的垂直位置并从 $chkVMBox
$chkForm.Controls.AddRange(…)
- 要创建动态布局,而无需预先知道元素的大小/数量:
我会尝试计算相对于不变量的控件的水平和垂直位置以及(最小)大小;例如,这些是从以下代码中的 $chkForm.Font
计算出来的(期望显然不一致:),请参阅 $hShift
和 $vShift
变量、它们的值和用法。
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
Remove-Variable chk* -ErrorAction SilentlyContinue
$nrOfNIC = 2
$nrOfDisks = 3
$nrOfPIP = 1
$allChkb = 1
$chkForm = New-Object System.Windows.Forms.Form
$chkForm.text = "Remove Resources"
$chkForm.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$hShift = $chkForm.Font.SizeInPoints
$vShift = $chkForm.Font.Height * 1.5 ### arbitrary ad hoc coefficient
$chkForm.StartPosition = 'CenterScreen'
$chkForm.FormBorderStyle = 'Fixed3D'
$chkForm.Icon = [System.Drawing.SystemIcons]::Question
$chkForm.Topmost = $true
$chkForm.AutoSize = $true
$chkForm.AutoSizeMode = 'GrowAndShrink'
$chkForm.MinimumSize = [System.Drawing.Size]::new(100,100)
# $chkForm.AutoScaleMode = 'Font'
$chkForm.MaximizeBox = $false
$chkForm.MinimizeBox = $false
$chkVMBox = new-object System.Windows.Forms.GroupBox
$chkVMBox.AutoSizeMode = 'GrowAndShrink'
$chkVMBox.AutoSize = $true
$chkVMBox.Location = New-Object System.Drawing.Point(10,10)
$chkVMBox.Text = 'VM resources'
if($nrOfDisks -gt 0) {
$chkVMDisks = new-object System.Windows.Forms.GroupBox
$chkVMDisks.Location = New-Object System.Drawing.Point($hShift,( $vShift+10))
$chkVMDisks.Text = 'DISKs'
$chkVMDisks.AutoSize = $true
$chkVMDisks.MinimumSize = [System.Drawing.Size]::new(($chkVMBox.Size.Width - $hShift),$vShift)
$chkVMDisks.AutoSizeMode = 'GrowAndShrink'
for($disk=0;$disk -lt $nrOfDisks;$disk++) {
$chkbDisk = New-Object System.Windows.Forms.Checkbox
$chkbDisk.Location = New-Object System.Drawing.Point($hShift,($vShift*($disk+1)))
$chkbDisk.AutoSize = $true
$chkbDisk.Text = "disk $disk"
$chkbDisk.TabIndex = $allChkb++
$chkVMDisks.Controls.Add($chkbDisk)
#$allChkb++
}
$chkVMBox.Controls.Add($chkVMDisks)
#$lastControl=$chkVMDisks
}
if($nrOfNIC -gt 0) {
#$vLocation = $lastControl.Bottom+$hShift
$vLocation = $chkVMDisks.Bottom + $vShift
$chkVMNICs = new-object System.Windows.Forms.GroupBox
$chkVMNICs.AutoSize = $true
$chkVMNICs.MinimumSize = [System.Drawing.Size]::new(($chkVMBox.Size.Width - $hShift),$vShift)
$chkVMNICs.AutoSizeMode = 'GrowAndShrink'
$chkVMNICs.Location = New-Object System.Drawing.Point($hShift,$vLocation)
$chkVMNICs.Text = 'NICs'
for($nic = 0;$nic -lt $nrOfNIC; $nic++) {
$chkbNIC = New-Object System.Windows.Forms.Checkbox
$chkbNIC.Location = New-Object System.Drawing.Point($hShift,($vShift*($nic+1)) )
# $chkbNIC.Anchor = 'left,top'
$chkbNIC.AutoSize = $true
$chkbNIC.Text = "nic $nic"
$chkbNIC.TabIndex = $allChkb++
$chkVMNICs.Controls.Add($chkbNIC)
#$allChkb++
}
$chkVMBox.Controls.Add($chkVMNICs)
#$lastControl = $chkVMNICs
}
#$vLocation = $lastControl.Bottom+$hShift
$vLocation = $chkVMNICs.Bottom + $vShift
$chkbVMdiag = New-Object System.Windows.Forms.Checkbox
$chkbVMdiag.Location = New-Object System.Drawing.Point($hShift,$vLocation)
$chkbVMdiag.AutoSize = $true
$chkbVMdiag.Text = "Boot Diagnostics"
$chkbVMdiag.TabIndex = $allChkb++
$chkVMBox.Controls.Add($chkbVMdiag)
$chkForm.Controls.Add($chkVMBox)
$vLocation = $chkVMBox.bottom + 20
$btOK = New-Object System.Windows.Forms.Button
$btOK.Location = New-Object System.Drawing.Point(15,$vLocation)
# $btOK.Size = New-Object System.Drawing.Size(70,20)
$btOK.AutoSize = $true
$btOK.Text = "OK"
$btOK.DialogResult = [System.Windows.Forms.DialogResult]::OK
$btCancel = New-Object System.Windows.Forms.Button
$btCancel.Location = New-Object System.Drawing.Point(95,$vLocation)
# $btCancel.Size = New-Object System.Drawing.Size(70,20)
$btCancel.AutoSize = $true
$btCancel.Text = "Cancel"
$btCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$chkForm.AcceptButton = $btOK
$chkForm.CancelButton = $btCancel
$chkForm.Controls.AddRange(@($btOK,$btCancel))
[void]$chkForm.ShowDialog()
$chkForm.Dispose()