arrays - 使用 Powershell 刷新数组复选框
问题描述
我正在尝试创建一个脚本,让用户从下拉列表中选择服务器。每个服务器都映射到一个唯一的数组,该数组进入一个 foreach 循环。循环遍历数组并在表单上打印一个带有数组中值的复选框。这没有问题。问题是当我从下拉列表中选择不同的服务器并单击“选择服务器”按钮时,数组中的新值不会覆盖现有值。换句话说,表单上的复选框值不会使用新的数组值进行更新。我想要发生的是,当您单击“选择服务器”按钮时,复选框值会更新以反映与其相应服务器关联的数组值。
这是一个例子。
- 从下拉列表中选择 ServerA
- 选择“选择服务器”
- 以下复选框将在复选框的表单中列出:@('Zero','One','Two','Three')
- 现在,如果您单击 ServerB 并选择“选择服务器”,我希望新的复选框会用这些值覆盖现有的复选框:@('0','1','2','3')
不幸的是,这些值没有更新。I need to have the array values update when the "Select Server" button is selected... Ive looked around at forums and have found some possible solutions but they all seems to fall short.
先感谢您。
function GenerateForm
{
$PC=
{
$hostname = $dropdown.SelectedItem
if ($hostname -eq "ServerA")
{ $CheckBoxLabels = @('Zero','One','Two','Three')
}
elseif($hostname -eq "ServerB")
{
$CheckBoxLabels = @('0','1','2','3')
}
$name = New-Object System.Windows.Forms.Label -Property @{
Text = "Start Time"
Location = "900, 220"
ForeColor = "Black"
Height = 22
Width = 200
}
$form1.Controls.Add($hostname)
$CheckBoxCounter = 1
$CheckBoxes = foreach($Label in $CheckBoxLabels)
{
$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.UseVisualStyleBackColor = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 104
$System_Drawing_Size.Height = 24
$CheckBox.Size = $System_Drawing_Size
$CheckBox.TabIndex = 2
$CheckBox.Text = $Label
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 27
# Make sure to vertically space them dynamically, counter comes in handy
$System_Drawing_Point.Y = 200 + (($CheckBoxCounter - 1) * 31) #Controls location on Y axis
$CheckBox.Location = $System_Drawing_Point
$CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0
# Give it a unique name based on our counter
$CheckBox.Name = "CheckBox$CheckBoxCounter"
$form1.Controls.Add($CheckBox)
# return object ref to array
$Global:CheckBox
# increment our counter
$CheckBoxCounter++
}
}
$form1 = New-Object System.Windows.Forms.Form
$form1.Text = "UCCE Log Collector - Version 2.0"
$form1.Name = "form1"
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 1150
$System_Drawing_Size.Height = 500
$form1.ClientSize = $System_Drawing_Size
$dropdown = New-Object System.Windows.Forms.ListBox
$dropdown.Location = New-Object System.Drawing.Point(10,50)
$dropdown.Size = New-Object System.Drawing.Size(100,20)
$dropdown.Height = 80
[void] $dropdown.Items.Add('ServerA')
[void] $dropdown.Items.Add('ServerB')
$form1.Controls.Add($dropdown)
######### Select Server Button
$SelectPC = New-Object System.Windows.Forms.Button
$SelectPC.TabIndex = 4
$SelectPC.Name = "SelectPC"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 120
$System_Drawing_Size.Height = 30
$SelectPC.Size = $System_Drawing_Size
$SelectPC.UseVisualStyleBackColor = $True
$SelectPC.Text = "Select Server"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0 # 0
$System_Drawing_Point.Y = 150 #150
$SelectPC.Location = $System_Drawing_Point
$SelectPC.DataBindings.DefaultDataSourceUpdateMode = 0
$SelectPC.add_Click($PC)
$form1.Controls.Add($SelectPC)
$result = $form1.ShowDialog()
$result
}
GenerateForm
解决方案
根据评论中的请求以容纳每个主机的可变数量的属性,首先我们将创建一个Panel
来保存我们的CheckBox
es 并将其添加到我们的Form
...
# Create a Panel to contain the dynamic collection of CheckBoxes
$HostPropertiesPanel = New-Object -TypeName 'System.Windows.Forms.Panel' -Property @{
# To illustrate the changing Size of the Panel
BackColor = [System.Drawing.Color]::GreenYellow
Location = New-Object -TypeName 'System.Drawing.Point' -Property @{
X = 27
Y = 200
}
Name = 'HostPropertiesPanel'
Size = [System.Drawing.Size]::Empty
}
$form1.Controls.Add($HostPropertiesPanel)
这消除了我们自己跟踪CheckBox
es 的需要,因为我们会知道它们都包含在 thisPanel
中。Size
最初是因为在选择主机之前Empty
没有es 可显示。CheckBox
在Click
/内部,$PC
我们将更改我们的主机属性的定义方式......
# Set $hostProperties to a Hashtable array for the corresponding value of $hostname
# The IsChecked values are arbitrary for demonstration purposes
#TODO: Replace if...elseif with a switch statement; see "help about_Switch"
$hostProperties = if ($hostname -eq "ServerA") {
@{ Label = 'Zero'; IsChecked = $false },
@{ Label = 'One'; IsChecked = $true },
@{ Label = 'Two'; IsChecked = $true },
@{ Label = 'Three'; IsChecked = $false }
}
elseif ($hostname -eq "ServerB") {
@{ Label = '0'; IsChecked = $true },
@{ Label = '1'; IsChecked = $false },
@{ Label = '2'; IsChecked = $false },
@{ Label = '3'; IsChecked = $true }
}
elseif ($hostname -eq "ServerC") {
@{ Label = 'A'; IsChecked = $true },
@{ Label = 'B'; IsChecked = $true },
@{ Label = 'C'; IsChecked = $false }
}
elseif ($hostname -eq "ServerD") {
# Create a property (Hashtable) for each day of the week
[Enum]::GetNames([DayOfWeek]) | ForEach-Object -Process {
@{
Label = $_
# Check the box if the day name has an odd number of vowels
IsChecked = [Regex]::Matches($_, '[aeiou]').Count % 2 -eq 1
}
}
}
else {
# Oops! A host with no properties defined was selected...
}
我们不是使用一个数组来存储标签,而另一个数组来存储状态,而是根据已选择的主机CheckBox
获得一个 s 数组并将其存储在.Hashtable
$hostProperties
在我们创建新的CheckBox
es 之前,我们必须从中删除任何现有的,并根据所选主机的属性$HostPropertiesPanel
调整它的大小......Length
# Remove all existing CheckBoxes from the Panel
$HostPropertiesPanel.Controls.Clear()
# Resize the Panel to accommodate the new count of host properties
$HostPropertiesPanel.Size = New-Object -TypeName 'System.Drawing.Size' -Property @{
Width = 104
Height = if ($hostProperties.Length -gt 0) {
($hostProperties.Length - 1) * 31 + 24
}
else {
0
}
}
然后我们只需要调整创建和配置每个CheckBox
...
for ($index = 0; $index -lt $hostProperties.Length; $index++) {
$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.UseVisualStyleBackColor = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 104
$System_Drawing_Size.Height = 24
$CheckBox.Size = $System_Drawing_Size
$CheckBox.TabIndex = 2
$CheckBox.Text = $hostProperties[$index].Label
$CheckBox.Checked = $hostProperties[$index].IsChecked
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0
# Make sure to vertically space them dynamically, counter comes in handy
$System_Drawing_Point.Y = $index * 31 #Controls location on Y axis
$CheckBox.Location = $System_Drawing_Point
$CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0
# Give it a unique name based on our counter
$CheckBox.Name = "CheckBox$index"
$HostPropertiesPanel.Controls.Add($CheckBox)
}
关键变化是使用in的 current检索 new 的Text
和Checked
值。CheckBox
$index
$hostProperties
最后的更改是更新主机名列表...
$dropdown.Items.AddRange(
@('ServerA', 'ServerB', 'ServerC', 'ServerD', 'ServerX')
)
$form1.Controls.Add($dropdown)
完整的脚本看起来像这样......
function GenerateForm {
$PC = {
$hostname = $dropdown.SelectedItem
# Set $hostProperties to a Hashtable array for the corresponding value of $hostname
# The IsChecked values are arbitrary for demonstration purposes
#TODO: Replace if...elseif with a switch statement; see "help about_Switch"
$hostProperties = if ($hostname -eq "ServerA") {
@{ Label = 'Zero'; IsChecked = $false },
@{ Label = 'One'; IsChecked = $true },
@{ Label = 'Two'; IsChecked = $true },
@{ Label = 'Three'; IsChecked = $false }
}
elseif ($hostname -eq "ServerB") {
@{ Label = '0'; IsChecked = $true },
@{ Label = '1'; IsChecked = $false },
@{ Label = '2'; IsChecked = $false },
@{ Label = '3'; IsChecked = $true }
}
elseif ($hostname -eq "ServerC") {
@{ Label = 'A'; IsChecked = $true },
@{ Label = 'B'; IsChecked = $true },
@{ Label = 'C'; IsChecked = $false }
}
elseif ($hostname -eq "ServerD") {
# Create a property (Hashtable) for each day of the week
[Enum]::GetNames([DayOfWeek]) | ForEach-Object -Process {
@{
Label = $_
# Check the box if the day name has an odd number of vowels
IsChecked = [Regex]::Matches($_, '[aeiou]').Count % 2 -eq 1
}
}
}
else {
# Oops! A host with no properties defined was selected...
}
# Don't execute any layout logic until all changes are complete
$HostPropertiesPanel.SuspendLayout()
# Remove all existing CheckBoxes from the Panel
$HostPropertiesPanel.Controls.Clear()
# Resize the Panel to accommodate the new count of host properties
$HostPropertiesPanel.Size = New-Object -TypeName 'System.Drawing.Size' -Property @{
Width = 104
Height = if ($hostProperties.Length -gt 0) {
($hostProperties.Length - 1) * 31 + 24
}
else {
0
}
}
for ($index = 0; $index -lt $hostProperties.Length; $index++) {
$CheckBox = New-Object System.Windows.Forms.CheckBox
$CheckBox.UseVisualStyleBackColor = $True
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 104
$System_Drawing_Size.Height = 24
$CheckBox.Size = $System_Drawing_Size
$CheckBox.TabIndex = 2
$CheckBox.Text = $hostProperties[$index].Label
$CheckBox.Checked = $hostProperties[$index].IsChecked
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0
# Make sure to vertically space them dynamically, counter comes in handy
$System_Drawing_Point.Y = $index * 31 #Controls location on Y axis
$CheckBox.Location = $System_Drawing_Point
$CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0
# Give it a unique name based on our counter
$CheckBox.Name = "CheckBox$index"
$HostPropertiesPanel.Controls.Add($CheckBox)
}
# All changes are complete, so resume layout logic
$HostPropertiesPanel.ResumeLayout()
}
$form1 = New-Object System.Windows.Forms.Form
$form1.Text = "UCCE Log Collector - Version 2.0"
$form1.Name = "form1"
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 1150
$System_Drawing_Size.Height = 500
$form1.ClientSize = $System_Drawing_Size
$dropdown = New-Object System.Windows.Forms.ListBox
$dropdown.Location = New-Object System.Drawing.Point(10, 50)
$dropdown.Size = New-Object System.Drawing.Size(100, 20)
$dropdown.Height = 80
$dropdown.Items.AddRange(
@('ServerA', 'ServerB', 'ServerC', 'ServerD', 'ServerX')
)
$form1.Controls.Add($dropdown)
######### Select Server Button
$SelectPC = New-Object System.Windows.Forms.Button
$SelectPC.TabIndex = 4
$SelectPC.Name = "SelectPC"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 120
$System_Drawing_Size.Height = 30
$SelectPC.Size = $System_Drawing_Size
$SelectPC.UseVisualStyleBackColor = $True
$SelectPC.Text = "Select Server"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0 # 0
$System_Drawing_Point.Y = 150 #150
$SelectPC.Location = $System_Drawing_Point
$SelectPC.DataBindings.DefaultDataSourceUpdateMode = 0
$SelectPC.add_Click($PC)
$form1.Controls.Add($SelectPC)
# Create a Panel to contain the dynamic collection of CheckBoxes
$HostPropertiesPanel = New-Object -TypeName 'System.Windows.Forms.Panel' -Property @{
# To illustrate the changing Size of the Panel
BackColor = [System.Drawing.Color]::GreenYellow
Location = New-Object -TypeName 'System.Drawing.Point' -Property @{
X = 27
Y = 200
}
Name = 'HostPropertiesPanel'
Size = [System.Drawing.Size]::Empty
}
$form1.Controls.Add($HostPropertiesPanel)
$name = New-Object System.Windows.Forms.Label -Property @{
Text = "Start Time"
Location = "900, 220"
ForeColor = "Black"
Height = 22
Width = 200
}
$form1.Controls.Add($name)
$result = $form1.ShowDialog()
$result
}
GenerateForm
另一种方法,特别是对于大量主机属性,将替换Panel
及其内容为CheckedListBox
.
推荐阅读
- ios - 使用 UITableViewAutomaticDimension 重新加载 tableview , Bounce
- android - 如何使用 exoplayer 自动启动视频?
- mysql - 连接到 MySQL 的正确方法是什么?
- angular - routerlink中间的Angular 6查询参数
- java - 如何在没有 JCL 的情况下使用 SAS (WPS) 运行 Java 代码
- java - 在Scala中创建具有任意类型和映射的三维数组
- keycloak - Keycloak:如何将 Keycloak 用户自动重定向到 OKTA SSO 页面而不是单击按钮?
- python - python - lxml - 如何优雅地标记文本中的单词?
- android - 接收器不兼容,需要地图!(安卓问题)
- ios - 如何启用 MPMediaItemArtwork 下一个/上一个按钮?