在wpf中虽然ObservableCollection<T>作为ListBox的Itemsource,很好,很强大!但是CollectionViewSource与ListBox才是天作之合!
wpf中ListBox支持分组显示,CollectionViewSource.GroupDescriptions为其实现了分组。废话不多说,下面上ListBox分组显示的Demo代码:
XAML:
<Window x:Class="WpfListGroup.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" Title="MainWindow" Height="450" Width="525"> <Window.Resources> <CollectionViewSource x:Key="employeeCollectionViewSource" Filter="employeeCollectionViewSource_Filter"> <CollectionViewSource.SortDescriptions> <!--排序描述--> <scm:SortDescription PropertyName="Num"/> </CollectionViewSource.SortDescriptions> <CollectionViewSource.GroupDescriptions> <!--分组描述--> <PropertyGroupDescription PropertyName="Title"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> <Style x:Key="ButtonFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#F3F3F3" Offset="0"/> <GradientStop Color="#EBEBEB" Offset="0.5"/> <GradientStop Color="#DDDDDD" Offset="0.5"/> <GradientStop Color="#CDCDCD" Offset="1"/> </LinearGradientBrush> <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/> <Style x:Key="nocheckedButtonStyle" TargetType="{x:Type Button}"> <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/> <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/> <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Padding" Value="1"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid Width="29.72"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver"> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="contentPresenter"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="90"/> </DoubleAnimationUsingKeyFrames> <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse"> <EasingColorKeyFrame KeyTime="0" Value="#FF2CA50B"/> </ColorAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"/> <VisualState x:Name="Disabled"/> </VisualStateGroup> <VisualStateGroup x:Name="FocusStates"> <VisualState x:Name="Unfocused"/> <VisualState x:Name="Focused"/> </VisualStateGroup> <VisualStateGroup x:Name="ValidationStates"> <VisualState x:Name="Valid"/> <VisualState x:Name="InvalidFocused"/> <VisualState x:Name="InvalidUnfocused"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Ellipse x:Name="ellipse" Fill="#FF75AB80" Margin="0" Stroke="{x:Null}" VerticalAlignment="Stretch" Width="16" Height="16"/> <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" > <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RenderTransformOrigin="0.5,0.5"> <ContentPresenter.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </ContentPresenter.RenderTransform> </ContentPresenter> </Microsoft_Windows_Themes:ButtonChrome> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"/> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="150"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <DockPanel Grid.Row="0" LastChildFill="True" > <TextBlock VerticalAlignment="Center" DockPanel.Dock="Left" Text="搜索:"/> <Button Content=" × " VerticalAlignment="Center" DockPanel.Dock="Right" Background="White" BorderBrush="{x:Null}" Margin="0" Style="{DynamicResource nocheckedButtonStyle}" HorizontalAlignment="Right" FontFamily="Forte" Foreground="White" ToolTip="清空" Click="btnClearKeyword_Click"/> <TextBox x:Name="txtEmployeeKeyword" VerticalAlignment="Center" TextChanged="txtEmployeeKeyword_TextChanged" /> </DockPanel> <ScrollViewer x:Name="scv1" Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> <ListBox x:Name="lbx1" SelectionMode="Extended" ItemsSource="{Binding Source={StaticResource ResourceKey=employeeCollectionViewSource}}"> <!--分组样式--> <ListBox.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander> <Expander.Header> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Margin="0,0,10,0"> <!--分组的组名--> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" /> <!--该分组元素(员工)的总和数--> <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount, StringFormat=(共{0}条)}"/> </StackPanel> <Line Grid.Column="1" SnapsToDevicePixels="true" X1="0" X2="1" Stretch="Fill" StrokeThickness="1"/> </Grid> </Expander.Header> <ItemsPresenter /> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </ListBox.GroupStyle> <!--右键菜单--> <ListBox.ContextMenu> <ContextMenu> <MenuItem Header="Show" Click="MenuItem_Click"/> </ContextMenu> </ListBox.ContextMenu> <!--“没有”绑定ListBox.ItemTemplate,是因为在Employee类重写了ToString()方法--> </ListBox> </ScrollViewer> <ScrollViewer x:Name="scv2" Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Visibility="Collapsed"> <ListBox Name="lbx2" ItemsSource="{Binding Source={StaticResource employeeCollectionViewSource}}" SelectionMode="Extended"> <!--按Ctrl键可多选--> <ListBox.ContextMenu> <ContextMenu> <!--右键菜单--> <MenuItem Header="Show" Click="MenuItem_Click"/> </ContextMenu> </ListBox.ContextMenu> </ListBox> </ScrollViewer> </Grid> </Window>