Powershell 集合视图

Powershell CollectionViews

我正在尝试使用 XAML 在 WPF ComboBox 中对项目进行分组,我发现 this 讨论了使用列表来驱动分组。但是示例 Code Behind 当然不是 Powershell,而且我花了很多时间摸索如何构建列表。有人可以指出有关 Powershell 中 CollectionViews 的好资源吗?我在 C/C++/C# 方面的经验为零,但我希望 Powershell 最终成为入门药物。 ;) 顺便说一句,我确实找到了这个,that 谈到在 XAML 中做集合视图,但是我的 collectionView 的内容将是动态的,所以我必须在代码中构建它。

顺便说一句,最终目标是一个看起来像这样的组合框...

Sets
   Arch
   MEP
   Viz

Packages
   RVT_2015
   RVT_2016
   MAX_2016

... 其中实际的套装和包是从一些用户自定义 XML 中动态提取的,用户可以选择一套或一个包。尝试列出两个列表并使用不令人沮丧的 UX 强制执行一个选择,效果不佳。所以我认为单个分组组合框可以很好地解决这个问题。

编辑:求进步!

$locations = @('Amsterdam', 'Berlin', 'London')
$sets = @('Arch', 'MEP', 'Viz')
$packages = @('RVT_2015', 'RVT_2016', 'MAX_2016')

[xml]$xaml = @"
<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="Window" Title="Initial Window" WindowStartupLocation = "CenterScreen" ResizeMode="NoResize"
    Width = "300" Height = "200" ShowInTaskbar = "True" Background = "lightgray"> 
    <StackPanel>
        <Label  Content="Define your job:" VerticalAlignment="Center" HorizontalAlignment="Left"  />
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Content="Location" VerticalAlignment="Center" HorizontalAlignment="Left"  />
            <ComboBox Name="Location" Width="200"  
                Grid.Row="0" Grid.Column="1"
                VerticalAlignment="Center" HorizontalAlignment="Right"
                VerticalContentAlignment="Center"  
                Margin="0,0,0,0">             
            </ComboBox>

            <Label Grid.Row="1" Grid.Column="0" Content="Target" VerticalAlignment="Center" HorizontalAlignment="Left"  />
            <ComboBox Name="Target"  
                Grid.Row="1" Grid.Column="1"
                VerticalAlignment="Center" HorizontalAlignment="Right"
                VerticalContentAlignment="Center" 
                Width="200" Margin="0,0,0,0">
                <ComboBox.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}"/>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </ComboBox.GroupStyle>
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </Grid>
    </StackPanel>
</Window>
"@

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$window=[Windows.Markup.XamlReader]::Load($reader)

$data = @() 
foreach ($target in $sets) {
    $data += New-Object PSObject -prop @{Name="$target";Category="Sets"}
}
foreach ($target in $packages) {
    $data += New-Object PSObject -prop @{Name="$target";Category="Packages"}
}

$listView = [System.Windows.Data.ListCollectionView]$data
$listView.GroupDescriptions.Add((new-object System.Windows.Data.PropertyGroupDescription "Category"))

$location = $window.findname("Location")
$location.ItemsSource = $locations

$target = $window.findname("Target")
$target.ItemsSource = $listView


$window.ShowDialog() | out-null

根据您在问题中链接的第一个示例,这里是 PowerShell 中的一个简单实现

Add-Type –assemblyName WindowsBase
Add-Type –assemblyName PresentationCore
Add-Type –assemblyName PresentationFramework

[xml]$xaml = @"
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ComboBox Name="comboBox" Width="200" VerticalAlignment="Top" HorizontalAlignment="Left"  
        Margin="10,20,0,0">
        <ComboBox.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ComboBox.GroupStyle>
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>
"@

$reader = (New-Object Xml.XmlNodeReader $xaml) 
$GUIWindow = [Windows.Markup.XamlReader]::Load( $reader ) 

$xaml.SelectNodes("//*[@Name]") | % {Set-Variable -Name ($_.Name) -Value $GUIWindow.FindName($_.Name)}

$data = @() 
$data += New-Object PSObject -prop @{Name="Arch";Category="Sets"}
$data += New-Object PSObject -prop @{Name="MEP";Category="Sets"}
$data += New-Object PSObject -prop @{Name="Viz";Category="Sets"}
$data += New-Object PSObject -prop @{Name="RVT_2015";Category="Packages"}
$data += New-Object PSObject -prop @{Name="RVT_2016";Category="Packages"}
$data += New-Object PSObject -prop @{Name="MAX_2016";Category="Packages"}

$lview = [System.Windows.Data.ListCollectionView]$data
$lview.GroupDescriptions.Add((new-object System.Windows.Data.PropertyGroupDescription "Category"))
$comboBox.ItemsSource = $lview


$GUIWindow.ShowDialog() | out-null

这是非常基础的,但您可以在此基础上进行构建。

编辑:

原来的答案是使用以下两行:

$lview = [System.Windows.Data.ListCollectionView]::new($data)
$lview.GroupDescriptions.Add([System.Windows.Data.PropertyGroupDescription]::new("Category"))

它们在 PS5 中工作,但会在所有以前版本的 PowerShell 中产生错误。解决方法是对 ListCollectionView 使用类型转换。这适用于 PS2.

$lview = [System.Windows.Data.ListCollectionView]$data
$lview.GroupDescriptions.Add((new-object System.Windows.Data.PropertyGroupDescription "Category"))

我已经用这个解决方法编辑了代码。