如何使用 XAML 在 WPF 中按首字母对 ListBoxItems 进行分组?
首先,这里是上一篇文章,涉及将 ListBox
AccountListBox 数据绑定到 AccountsCollection.cs
类中的 ObservableCollection
帐户。
所以现在我有一个绑定对象 AccountsCollection 和一个名为 AccountTemplate 的 DataTemplate,用于在资源中定义我的 ListBox:
<Window.Resources>
<controller:AccountsWindowController x:Key="AccountsCollection" />
<DataTemplate x:Key="AccountTemplate">
<DockPanel>
<Button Name="EditButton"
DockPanel.Dock="Right"
Margin="3 0 3 0"
VerticalAlignment="Center"
Content="Edit" />
<Button Name="DeleteButton"
DockPanel.Dock="Right"
Margin="3 0 3 0"
VerticalAlignment="Center"
Content="Delete" />
<TextBlock Name="AccountName"
VerticalAlignment="Center"
Text="{Binding Name}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
<Window.Resources>
下面是与 LisBox 本身相关的代码:
<ListBox Name="AccountsListBox"
Margin="12,38,12,41"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Accounts,
Source={StaticResource ResourceKey=AccountsCollection}}"
ItemTemplate="{StaticResource ResourceKey=AccountTemplate}"
MouseDoubleClick="AccountsListBox_MouseDoubleClick">
</ListBox>
我希望我的列表被设计为按起始字母对所有帐户进行分组并显示列表中的字母(我还想对该字母标题应用一些设计)。最终结果应该是这样的:
感谢您的帮助!
更新:这是成功实现分组的代码。
<Window x:Class="Gui.Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:entities="clr-namespace:Entities.Accounts;assembly=Entities"
xmlns:contollers="clr-namespace:Gui.Wpf.Controllers"
xmlns:converters="clr-namespace:Gui.Wpf.Converters"
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="MainWindow"
Width="525"
Height="350" >
<Window.Resources>
<!-- Main window controller -->
<contollers:MainWindowController
x:Key="MainWindowController" />
<!-- Converter for first letter extraction from the account name -->
<converters:FirstLetterConverter x:Key="FirstLetterConv" />
<!-- View source for the AccountsListBox -->
<CollectionViewSource
x:Key="AccountsView"
Source="{Binding Accounts, Source={StaticResource ResourceKey=MainWindowController}}">
<!-- Sorting -->
<CollectionViewSource.SortDescriptions>
<componentModel:SortDescription PropertyName="AccountName" />
</CollectionViewSource.SortDescriptions>
<!-- Grouping -->
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="AccountName" Converter="{StaticResource ResourceKey=FirstLetterConv}" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<!-- Data template for the type Account -->
<DataTemplate
DataType="{x:Type entities:Account}">
<DockPanel>
<Button
Name="DeleteButton"
DockPanel.Dock="Right"
Margin="3, 1, 3, 1"
VerticalAlignment="Center"
Content="Delete" />
<Button
Name="EditButton"
DockPanel.Dock="Right"
Margin="3, 1, 3, 1"
VerticalAlignment="Center"
Content="Edit" />
<TextBlock
Name="AccountNameTextBlock"
VerticalAlignment="Center"
Text="{Binding AccountName}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
<!-- Data template for AccountListBox grouping -->
<DataTemplate x:Key="GroupingHeader">
<TextBlock Text="{Binding Path=Name}" Background="Black" Foreground="White" />
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox
Name="AccountsListBox"
Width="300"
Height="200"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource ResourceKey=AccountsView}}"
HorizontalContentAlignment="Stretch" >
<ListBox.GroupStyle>
<GroupStyle
HeaderTemplate="{StaticResource ResourceKey=GroupingHeader}" />
</ListBox.GroupStyle>
</ListBox>
</Grid>
First, here is the previous post that deals with the ListBox
AccountListBox data binding to my ObservableCollection<Account>
Accounts from the AccountsCollection.cs
class.
So now I have a binding object AccountsCollection and a DataTemplate named AccountTemplate for my ListBox defined in the resources:
<Window.Resources>
<controller:AccountsWindowController x:Key="AccountsCollection" />
<DataTemplate x:Key="AccountTemplate">
<DockPanel>
<Button Name="EditButton"
DockPanel.Dock="Right"
Margin="3 0 3 0"
VerticalAlignment="Center"
Content="Edit" />
<Button Name="DeleteButton"
DockPanel.Dock="Right"
Margin="3 0 3 0"
VerticalAlignment="Center"
Content="Delete" />
<TextBlock Name="AccountName"
VerticalAlignment="Center"
Text="{Binding Name}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
<Window.Resources>
And here is the code related to the LisBox itself:
<ListBox Name="AccountsListBox"
Margin="12,38,12,41"
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Accounts,
Source={StaticResource ResourceKey=AccountsCollection}}"
ItemTemplate="{StaticResource ResourceKey=AccountTemplate}"
MouseDoubleClick="AccountsListBox_MouseDoubleClick">
</ListBox>
I want my list to be designed to group all accounts by starting letter and to show that letter in the list (Also I want to apply some design to that letter header). The final result should be something like this:
Thanks for all the help!
UPDATE: Here's the code with grouping successfully implemented.
<Window x:Class="Gui.Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:entities="clr-namespace:Entities.Accounts;assembly=Entities"
xmlns:contollers="clr-namespace:Gui.Wpf.Controllers"
xmlns:converters="clr-namespace:Gui.Wpf.Converters"
xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="MainWindow"
Width="525"
Height="350" >
<Window.Resources>
<!-- Main window controller -->
<contollers:MainWindowController
x:Key="MainWindowController" />
<!-- Converter for first letter extraction from the account name -->
<converters:FirstLetterConverter x:Key="FirstLetterConv" />
<!-- View source for the AccountsListBox -->
<CollectionViewSource
x:Key="AccountsView"
Source="{Binding Accounts, Source={StaticResource ResourceKey=MainWindowController}}">
<!-- Sorting -->
<CollectionViewSource.SortDescriptions>
<componentModel:SortDescription PropertyName="AccountName" />
</CollectionViewSource.SortDescriptions>
<!-- Grouping -->
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="AccountName" Converter="{StaticResource ResourceKey=FirstLetterConv}" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<!-- Data template for the type Account -->
<DataTemplate
DataType="{x:Type entities:Account}">
<DockPanel>
<Button
Name="DeleteButton"
DockPanel.Dock="Right"
Margin="3, 1, 3, 1"
VerticalAlignment="Center"
Content="Delete" />
<Button
Name="EditButton"
DockPanel.Dock="Right"
Margin="3, 1, 3, 1"
VerticalAlignment="Center"
Content="Edit" />
<TextBlock
Name="AccountNameTextBlock"
VerticalAlignment="Center"
Text="{Binding AccountName}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
<!-- Data template for AccountListBox grouping -->
<DataTemplate x:Key="GroupingHeader">
<TextBlock Text="{Binding Path=Name}" Background="Black" Foreground="White" />
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox
Name="AccountsListBox"
Width="300"
Height="200"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource ResourceKey=AccountsView}}"
HorizontalContentAlignment="Stretch" >
<ListBox.GroupStyle>
<GroupStyle
HeaderTemplate="{StaticResource ResourceKey=GroupingHeader}" />
</ListBox.GroupStyle>
</ListBox>
</Grid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
CollectionViewSource
和转换器来提取第一个字母:转换器:
如果要将样式应用于组,可以使用
GroupStyle
属性:You can use a
CollectionViewSource
, and a converter to extract the first letter:Converter:
If you want to apply a style to the group, you can use the
GroupStyle
property:下面是一个非常相似的解决方案示例:
首先,我们需要为您的 DataContext 生成一个更好的集合 - 这是一个您可以根据您的目的轻松修改的示例 -
然后我们只需要嵌套的 ItemsControls对于用户界面 -
我们得到这个:
Here is an example of a solution that is very similar:
Firstly, we need to generate a better collection for your
DataContext
- here's an example that you could easily modify for your purposes -then we just need nested ItemsControls for the UI -
and we get this: