欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

Windows PowerShell每周提示(40):多选列表框及更多的技巧

诸位,好消息:你现在能放松了,因为重要的日子终于到来了。

上周的提示中,我们解释了如何通过Windows PowerShell.NET Framework来创建可以让用户从列表框中进行选择的对话框。在介绍了创建列表框的基本方法后,我们承诺在本周的提示中,我们将展示如何对这个列表框进行一些装饰工作。此外,我们还承诺将向你展示如何创建多选列表框。这有可能是个错误,毕竟,毫无疑问,当我们承诺向你展示如何装饰列表框时,你们中的很多人在过去的一周中可能寝食难安,焦急等待着这一刻的到来。好的,现在你能放松了:现在是离开基本的列表框的时候了。然我们开始向你展示如何创建多选列表框的代码(换句话说,一个能让你一次选择多个项目的列表框)。我们今天不打算详细解释其中的大部分代码,因为这些在上周的提示中已经解释了。但是不要担心:我们将解释标准列表框和多选列表框之间有差异的代码。

如果我们无法完成此事的话,我们也会寝食难安的。

但是先提重要的事:

$x = @()

 

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

 

$objForm = New-Object System.Windows.Forms.Form

$objForm.Text = "Data Entry Form"

$objForm.Size = New-Object System.Drawing.Size(300,200)

$objForm.StartPosition = "CenterScreen"

 

$objForm.KeyPreview = $True

 

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")

    {

        foreach ($objItem in $objListbox.SelectedItems)

            {$x += $objItem}

        $objForm.Close()

    }

    })

 

$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")

    {$objForm.Close()}})

 

$OKButton = New-Object System.Windows.Forms.Button

$OKButton.Location = New-Object System.Drawing.Size(75,120)

$OKButton.Size = New-Object System.Drawing.Size(75,23)

$OKButton.Text = "OK"

 

$OKButton.Add_Click(

   {

        foreach ($objItem in $objListbox.SelectedItems)

            {$x += $objItem}

        $objForm.Close()

   })

 

$objForm.Controls.Add($OKButton)

 

$CancelButton = New-Object System.Windows.Forms.Button

$CancelButton.Location = New-Object System.Drawing.Size(150,120)

$CancelButton.Size = New-Object System.Drawing.Size(75,23)

$CancelButton.Text = "Cancel"

$CancelButton.Add_Click({$objForm.Close()})

$objForm.Controls.Add($CancelButton)

 

$objLabel = New-Object System.Windows.Forms.Label

$objLabel.Location = New-Object System.Drawing.Size(10,20)

$objLabel.Size = New-Object System.Drawing.Size(280,20)

$objLabel.Text = "Please make a selection from the list below:"

$objForm.Controls.Add($objLabel)

 

$objListbox = New-Object System.Windows.Forms.Listbox

$objListbox.Location = New-Object System.Drawing.Size(10,40)

$objListbox.Size = New-Object System.Drawing.Size(260,20)

 

$objListbox.SelectionMode = "MultiExtended"

 

[void] $objListbox.Items.Add("Item 1")

[void] $objListbox.Items.Add("Item 2")

[void] $objListbox.Items.Add("Item 3")

[void] $objListbox.Items.Add("Item 4")

[void] $objListbox.Items.Add("Item 5")

 

$objListbox.Height = 70

$objForm.Controls.Add($objListbox)

$objForm.Topmost = $True

 

$objForm.Add_Shown({$objForm.Activate()})

[void] $objForm.ShowDialog()

 

$x

很有趣,标准列表框很多选列表框之间只有两个真正不同的地方:1) 在一个多选列表框中你必须向SelectionMode属性指定一个值。2) 在多选列表框中你必须以数组方式来处理选择的项而不是以单一选择项处理。无论相信与否,这就是将标准列表转换为多选列表框的所有内容。

让我们首先从向SelectionMode属性指定一个值开始:

$objListbox.SelectionMode = "MultiExtended"

如你所见,和你曾写过的代码相比这并不复杂。在本例中我们将SelectionMode设置为MultiExtended。这意味着什么?好的,首先它说明你能在列表框中多选列表项。你要做的是单击某个列表项,然后按住Ctrl键然后单击另一项。(可以再选择另外一个列表项……)另外,你能单击某一列表项,然后按住Shift键然后单击第二个列表项,这将使得在这些项之间的列表项都被选中。例如,假设我们有以下列表框:

现在,在MultiExtended模式下,假设你单击Item 1,然后按住Shift键,随后单击Item 4,会发生些什么呢?如图所示:

很漂亮吧?

或者,你可以设置SelectionModeMultiSimple。在这种情况下,按住Shift键将不会选择一个范围内列表项。反之,在此模式下Shift键的功能和Ctrl键的功能类似:它允许选择一个额外的项目。下图是我们在MultiSimple模式下当我们单击Item 1然后按住Shift键然后选择Item 4所发生的:

这是好还是坏?都不是,真的,这仅仅是一个不同点。

注意. 如果你完全不想要多选列表框的话,如果你只想要一个简单古老的单选列表框的话,那么很简单,那就不要为SelectionMode感到烦恼。

顺便说一句,在MultiExtended模式下,你也能使用方向键(同时使用或者不使用Shift键)来在列表框中选择列表项。还请你自己尝试下。

现在,确定在列表框中所选项目的代码是什么?上周,当我们讨论标准列表框时,抓取所选项的值并且关闭对话框的代码如下所示:

$OKButton.Add_Click({$x=$objListbox.SelectedItem;$objForm.Close()})

这很简单,因为我们不需要考虑如何处理列表框中多于一个选中项。然而,对多选列表框而言,我们可以多选一个以上的列表项。我们如何处理这个问题?好的,下面是一种方法:

$OKButton.Add_Click(

   {

        foreach ($objItem in $objListbox.SelectedItems)

            {$x += $objItem}

        $objForm.Close()

   })

在我们解释这个代码块如何工作时,需要指出,在脚本最开始的一行,我们创建了一个名为$x的空数组:

$x = @()

我们为什么这么做?因为我们需要它来存放我们在列表框中选择的项,而数组则正适合此项要求。

注意. 好的,从技术上来说,这不对:我们不需要存放列表框内所有所选项的变量,作为替代,我们可以只是简单地处理$objListbox.SelectedItems的属性值。选择数组是因为我们认为这能让人们更简单的理解整个处理过程。

对我们的代码块而言,首先是创建了一个foreach循环来遍历在SelectedItems(如名称所示,这是一个包含在列表框中所选项的多值属性)属性中所有项:

foreach ($objItem in $objListbox.SelectedItems)

在循环内我们使用以下这行代码来将每一项添加进数组$x

$x += $objItem

一旦我们循环完所有选择的列表项,就调用Close方法来关闭窗体。一旦窗体关闭,我们就回显$x的值。这就是最行一行代码所要做的:

$x

假设我们选择了第134个列表项,那么我们应当得到以下结果:

Item 1

Item 3

Item 4

顺便说一句,你也能对标准列表框使用相同的方法,唯一区别是SelectedItems属性将永远不会出现一个以上的值。这完全取决于你。现在你就有了一个多选列表框。现在你打算如何装饰你的列表框呢?好的,老实说,你能对列表框所做的装饰工作并不多。(因此,你需要使用复选列表框或者列表视图,这两项将在未来的提示中所提及。)然而,你能做的一件事是指定一个每次当列表框出现时将被选择的默认项。例如,假设我们想要Item 2成为默认项。这很不错,下面的代码将帮我们处理这件事。只需在添加所有项至列表框的代码后添加以下代码:

$objListBox.SelectedItem = "Item 2"

现在运行脚本然后显示列表框,你应当看到:

不坏吧?

另一个你觉得有用的属性是Sorted属性。当我们创建列表框时我们以字母顺序添加了所有的列表项:

[void] $objListbox.Items.Add("Item 1")

[void] $objListbox.Items.Add("Item 2")

[void] $objListbox.Items.Add("Item 3")

[void] $objListbox.Items.Add("Item 4")

[void] $objListbox.Items.Add("Item 5")

这很不错,但是所有事并非一直都有可能出现。例如,你从文本文件中读取信息,无法保证所有信息都是以字母顺序排列。如果你想要,在添加到列表框之前,你能使用Sort-Object cmdlet来对这些值排序。此外,你能设置Sorted属性为真来让列表框问你处理所有的这些事:

$objListBox.Sorted = $True

假设我们使用以下代码块来向列表框中添加列表项,而代码块中的列表项没有以字母顺序排序:

[void] $objListbox.Items.Add("Item 5")

[void] $objListbox.Items.Add("Item 2")

[void] $objListbox.Items.Add("Item 4")

[void] $objListbox.Items.Add("Item 1")

[void] $objListbox.Items.Add("Item 3")

这意味着什么?这意味着我们的列表框将会反映出列表项添加的顺序:

好的,这并不好。但是这没什么,注意当我们设置Sorted属性为真后的区别:

酷。

最后是改变列表框的前景色和背景色,也包括显示每一项的字体。你想要这么做?好的,这由你决定。然而,如果你有兴趣,那么这些代码将对你有帮助:

$objListBox.BackColor = "cyan"

$objListBox.Forecolor = "blue"

$objListBox.Font = "Arial Black"

下面是结果:

像我们所说的,由你来决定这是否值得做。

这是本周的所有内容,诸位下周见。下周的提示将是什么内容?好的,我们打算向你展示一些真的很酷的内容,我们打算……你明白了,我们最好什么都不要说了。毕竟本周你需要一些休息。

英文原文

http://www.microsoft.com/technet/scriptcenter/resources/pstips/may08/pstip0509.mspx

已发表 2008年7月13日 19:12 作者 ghjconan

评论

禁止匿名发表评论