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"))
我已经用这个解决方法编辑了代码。
我正在尝试使用 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"))
我已经用这个解决方法编辑了代码。