WPF:分类的可收缩的WrapPanel列表
效果如下,WrapPanel样式的列表同时支持分类。
如果点击分类列表Header后,相应的类别子元素会收缩。
起初想用ListBox实现,但是很快被WrapPanel和GroupStyle整的一头雾水。同时对WPF中数据源ICollectionView的分类是采用PropertyGroupDescription这种靠反射来执行的逻辑表示不爽,最终定自己写一个类似的控件。
核心类型WrapList继承自WrapPanel。
三个非常基础的WPF常见控件/数据样式选项:HeaderStyle,HeaderTemplate和ItemTemplate分别设置类型Header的Style和Data Template,以及子元素的Data Template。
同时还有一个WrapListGroupHeader控件代表类型Header的显示控件,它就是一个ToggleButton,在点击后会自动收缩其子项目。
ItemsSource类型是object,但是它只支持IEnumerable<IGrouping<TKey, TElement>>类型,没有使用WPF中ICollectionView的PropertyGroupDescription,而是LINQ中GroupBy返回的原生结果。当ItemsSource被设置后,元素即会被显示。
那么数据源的设置的示例代码:
//mylist是WrapList控件的名称
//设置WrapList的数据源为1-50余3的结果
var groups = Enumerable.Range(1, 50).GroupBy(i => i % 3);
mylist.ItemsSource = groups;
接着定义XAML上的WrapList。最好把WrapList抱在横向的ScrollViewer中,同时由于WrapList继承自WrapPanel,因此可以适当设置ItemWidth和ItemHeight属性。最上方示例程序截图的界面XAML:
<!-- loc是WrapList所在的命名空间 -->
<!-- 设置好横向滚动条 -->
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<!-- WrapList控件 -->
<loc:WrapList x:Name="mylist" ItemWidth="100">
<!-- Header样式 -->
<loc:WrapList.HeaderStyle>
<Style TargetType="loc:WrapListGroupHeader">
<Setter Property="Background" Value="Gray"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Padding" Value="0 3"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</loc:WrapList.HeaderStyle>
<!-- 子成员数据模板 -->
<loc:WrapList.ItemTemplate>
<DataTemplate>
<Border Margin="5">
<StackPanel Orientation="Horizontal">
<Ellipse Width="5" Height="5" Fill="YellowGreen" Margin="0 0 7 0"/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</Border>
</DataTemplate>
</loc:WrapList.ItemTemplate>
<!-- Header数据模板 -->
<loc:WrapList.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding StringFormat=除以3余:\{0\}}"/>
</DataTemplate>
</loc:WrapList.HeaderTemplate>
</loc:WrapList>
</ScrollViewer>
当前版本的源代码下载
下载地址
注意:此为微软SkyDrive存档,请用浏览器直接下载,用某些下载工具可能无法下载
示例程序运行环境:.NET Framework 4.0 Client Profile
源代码环境:Microsoft Visual C# 2010 Express
TAG: