我可以使用 WrapPanel 来组织 ListView 组 headers 吗?
Can I use a WrapPanel to organize ListView group headers?
我希望能够使用 WrapPanel 按组 header 而不是按项目进行包装。
我已经为绑定到 ObservableCollection studentlist
的 ListView 实现了以下 ICollectionView view
:
view = CollectionViewSource.GetDefaultView(studentlist);
view.GroupDescriptions.Add(new PropertyGroupDescription("sectionoutput"));
view.SortDescriptions.Add(new SortDescription("sectionoutput", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("displayname", ListSortDirection.Ascending));
XAML 包含样式资源,用于设置群组模板 header:
<Style x:Key="ContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="{Binding Name, Mode=OneWay, Converter={StaticResource expanderconverter}}">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此样式用作 ListView 的组样式:
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/>
</ListView.GroupStyle>
...
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding displayname}">
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
照原样,代码显示了一个垂直列表,学生姓名按 header 分组,列出了他们的部分编号。但是我想在水平方向上按顺序列出组。
我知道我可以使用 WrapPanel 组织 ListView 中的项目:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ItemWidth="150">
</WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
但是这段代码只是并排显示一组中的学生,而不是并排显示组本身。我想做的是将组本身水平包裹起来。我试过在style资源中实现一个wrap panel,但是没有成功,一直想知道有没有办法按组换行。
我认为可以通过切换到 TreeView 并将组转换为项目来实现此目的。但如果可能的话,我更愿意使用 ListView,因为我的程序实现了一个将 ListView 作为参数的 class。
假设有一个 ViewModel
,它是下面发布的 XAML 的 DataContext,它包含一个名为 GroupsViewModel
的 ObservableCollection<GroupViewModel>
。
GroupViewModel
仅仅有一个名为 GroupName
的 属性,这是要显示的组的名称,它有一个 属性 ObservableCollection<StudentViewModel>
。
StudentViewModel
有 属性 displayName
来显示学生的姓名。
这么说,通过使用一个Expander
和2个嵌套的ListBox
就可以得到你所要求的,就像下面的代码:
<ListBox ItemsSource="{Binding GroupsViewModel}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Expander HorizontalAlignment="Left" IsExpanded="True" Header="{Binding GroupName}">
<ListBox ItemsSource="{Binding StudentViewModel}" HorizontalAlignment="Left">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding displayname}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Expander>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
GroupStyle
有一个 Panel
属性,您可以将其设置为 ItemsPanelTemplate
和 WrapPanel
:
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource ContainerStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListView.GroupStyle>
我希望能够使用 WrapPanel 按组 header 而不是按项目进行包装。
我已经为绑定到 ObservableCollection studentlist
的 ListView 实现了以下 ICollectionView view
:
view = CollectionViewSource.GetDefaultView(studentlist);
view.GroupDescriptions.Add(new PropertyGroupDescription("sectionoutput"));
view.SortDescriptions.Add(new SortDescription("sectionoutput", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("displayname", ListSortDirection.Ascending));
XAML 包含样式资源,用于设置群组模板 header:
<Style x:Key="ContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="{Binding Name, Mode=OneWay, Converter={StaticResource expanderconverter}}">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此样式用作 ListView 的组样式:
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/>
</ListView.GroupStyle>
...
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding displayname}">
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
照原样,代码显示了一个垂直列表,学生姓名按 header 分组,列出了他们的部分编号。但是我想在水平方向上按顺序列出组。
我知道我可以使用 WrapPanel 组织 ListView 中的项目:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ItemWidth="150">
</WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
但是这段代码只是并排显示一组中的学生,而不是并排显示组本身。我想做的是将组本身水平包裹起来。我试过在style资源中实现一个wrap panel,但是没有成功,一直想知道有没有办法按组换行。
我认为可以通过切换到 TreeView 并将组转换为项目来实现此目的。但如果可能的话,我更愿意使用 ListView,因为我的程序实现了一个将 ListView 作为参数的 class。
假设有一个 ViewModel
,它是下面发布的 XAML 的 DataContext,它包含一个名为 GroupsViewModel
的 ObservableCollection<GroupViewModel>
。
GroupViewModel
仅仅有一个名为 GroupName
的 属性,这是要显示的组的名称,它有一个 属性 ObservableCollection<StudentViewModel>
。
StudentViewModel
有 属性 displayName
来显示学生的姓名。
这么说,通过使用一个Expander
和2个嵌套的ListBox
就可以得到你所要求的,就像下面的代码:
<ListBox ItemsSource="{Binding GroupsViewModel}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Expander HorizontalAlignment="Left" IsExpanded="True" Header="{Binding GroupName}">
<ListBox ItemsSource="{Binding StudentViewModel}" HorizontalAlignment="Left">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding displayname}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Expander>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
GroupStyle
有一个 Panel
属性,您可以将其设置为 ItemsPanelTemplate
和 WrapPanel
:
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource ContainerStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListView.GroupStyle>