首页 > 解决方案 > 将一个项目的数组加载到 WPF 列表框中

问题描述

我遇到此代码的问题,如果数组中的项目返回少于两个字符串,则字符串显示为列表。

例如,如果我有两个集群。列表框会给我选择让我们说测试集群和开发集群的选项;但是,如果只有 Test-Cluster 是唯一可用的集群,则列表框会将字符串的每个字母显示为列表框中的不同选项。我似乎无法弄清楚为什么。见图片:

在此处输入图像描述

#event: when Environment is selected
$wpFBoxEnvironment.Add_DropDownClosed({
    Disconnect-VIServer * -Confirm:$false
    #empty VCenters inside form 
    $wpFBoxSrcVCenter.Items.Clear()
    $wpFListTgtVCenters.Items.Clear()
    #empty Source VMs inside form 
    $wpFListSrcVMs.Items.Clear()
    #validate VI servers connetion and connect if session doesn't exist
    $VServers = $vdiEnvironments | 
                Where-Object Env -like $wpFBoxEnvironment.Text

    #notify use to wait for vCenter server login
    Write-Host "Logging in to all $($wpFBoxEnvironment.Text) servers. Please wait..."

    foreach ($VServer in $VServers) {
        $sessionID = ($global:DefaultVIServers | Where-Object -FilterScript {$_.Name -like $VServer.Name}).sessionId
        if ($sessionID) {
            Connect-VIServer -Server $VServer.Name -Session $sessionID
        } elseif ($credential) {
            Connect-VIServer -Server $VServer.Name -Credential $credential
        } else {
            throw 'Connection Error'
        }
    }

    $clusters = Get-Cluster | Select-Object Name, Uid
    $clusters | ForEach-Object {
        $_ | Add-Member -MemberType NoteProperty -Name VCName -Value $_.Uid.Split('@')[1].Split(':')[0]
    }

    $datastores = Get-Datastore | Select-Object -Property Name, DatastoreBrowserPath, FreeSpaceMB, CapacityMB
    $datastores | ForEach-Object {
        $_ | Add-Member -MemberType NoteProperty -Name VCName -Value $_.DatastoreBrowserPath.Split('\')[1].replace('@443','')
        $_.FreeSpaceMB = [int]$_.FreeSpaceMB
        $_.CapacityMB  = [int]$_.CapacityMB
    }

    $portgroups = Get-VDPortgroup | Select-Object VlanConfiguration, Name, NumPorts, Uid | ? VlanConfiguration -notlike "*0-4094*"
    $portgroups | ForEach-Object {
        $_ | Add-Member -MemberType NoteProperty -Name VCName -Value $_.Uid.Split('@')[1].Split(':')[0]
        $_.NumPorts = [int]$_.NumPorts
    }

    $vCenters = @()
    foreach ($vCenter in $VDIEnvironments) {
        #Find single clusters and padd array
        if (($clusters | ? VCName -like $vCenter.Name).Count -eq 1) {
            $clusters += ("-----")
        }
        $vCenter |
            Add-Member -MemberType NoteProperty -Name TargetCluster -Value (
                $clusters | ? VCName -like $vCenter.Name
            )[0].Name -Force
        $vCenter |
            Add-Member -MemberType NoteProperty -Name Clusters -Value $(
                $clusters | ? VCName -like $vCenter.Name
            ).Name -Force
        $vCenter |
            Add-Member -MemberType NoteProperty -Name TargetDatastore -Value $(
                $datastores | ? VCName -like $vCenter.Name | Sort-Object -Descending FreeSpaceMB
            )[0].Name -Force
        $vCenter |
            Add-Member -MemberType NoteProperty -Name Datastores -Value $(
                $datastores | ? VCName -like $vCenter.Name
            ).Name -Force 
        $vCenter |
            Add-Member -MemberType NoteProperty -Name TargetPortgroup -Value (
                $portgroups | ? VCName -like $vCenter.Name | Sort-Object -Descending NumPorts
            )[0].Name -Force
        $vCenter |
            Add-Member -MemberType NoteProperty -Name Portgroups -Value $(
                $portgroups | ? VCName -like $vCenter.Name
            ).Name -Force

        $vCenters += $vCenter
    }

    #fill VCenters inside form from selected Environment
    $selectedVCenters = $vCenters | 
        Where-Object Env -like $wpFBoxEnvironment.Text |
        Where-Object Datastores -ne $Null
    $selectedVCenters | ForEach-Object {
        $wpFBoxSrcVCenter.Items.Add($_.Name)
        $wpFListTgtVCenters.Items.Add($_) 
        $wpFListTgtVCenters.SelectedItems.Add($_)
    }
})
<GridViewColumn Header="Target Cluster" 
                                     Width="160" >
                     <GridViewColumn.CellTemplate>
                        <DataTemplate>
                           <ComboBox ItemsSource="{Binding 'Clusters'}"
                                     SelectedItem="{Binding Path='TargetCluster', Mode=TwoWay}"
                                     Width="145"
                            />
                        </DataTemplate>
                     </GridViewColumn.CellTemplate>
                  </GridViewColumn>

标签: wpfpowershellxamllistbox

解决方案


我认为这是因为您正在迭代一个数组,或者在单个项目的情况下,一个字符串。尝试预定义您的数组,然后将 ( +=) 添加到它。这样,在单个字符串的情况下,它仍然是一个数组:

编辑:

查看数据,您可能必须通过换行将单个字符串显式转换为数组$_@(..)获得:@($_)

这会将字符串转换为单值数组,或保留现有数组。更多信息:about_arrays

...
#fill VCenters inside form from selected Environment

$selectedVCenters = @()
$selectedVCenters += $vCenters | 
   Where-Object Env -like $wpFBoxEnvironment.Text | 
   Where-Object Datastores -ne $Null
$selectedVCenters | ForEach-object {
   $wpFBoxSrcVCenter.Items.Add($_.Name)
   $wpFListTgtVCenters.Items.Add(@($_)) 
   $wpFListTgtVCenters.SelectedItems.Add($_)
}

推荐阅读