WPF - Group分组对ListBox等列表样式的约束
原文:WPF - Group分组对ListBox等列表样式的约束
在做WPF主题支持时,出现一个分组引起的莫名错误,可是折腾了我一番。在没有使用样式时,列表分组很正常,使用了别人写的ListBox列表样式后,发现GroupItem分组区没有内容,是空的,本篇把这一问题的解决过程给大家说一下,做主题时可以注意分组对列表样式的限制了。
ListBox增加分组
WPF为ItemsControl提供很多的样式扩展,要想实现列表分组也很简单,只需要做以下几步就可以了:
- 给列表控件增加分组样式

代码
<Style x:Key="GroupContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<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="" SnapsToDevicePixels="true" X1="" X2="" Stretch="Fill" StrokeThickness=""/>
</Grid>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>GroupStyle gs = new GroupStyle();
gs.ContainerStyle = Application.Current.TryFindResource("GroupContainerStyle") as Style;
lbModule.GroupStyle.Add(gs); 给数据增加分组

代码
<UserControl.Resources>
<CollectionViewSource Source="{x:Static oea:ApplicationModel.DefaultBusinessObjectInfos}" x:Key="cvs">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Catalog" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
使用ListBox样式后
用了别人的一个ListBox样式文件,样式如下:

代码
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource PrimaryColor}" Offset="" />
<GradientStop Color="{DynamicResource SecondaryColor}" Offset="" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="" CornerRadius="4,4,4,4">
<Grid>
<ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false" x:Name="scrollViewer">
<StackPanel Margin="" IsItemsHost="true"/>
<!--<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />-->
</ScrollViewer>
<Border CornerRadius="4,4,4,4" Visibility="Collapsed" x:Name="border" Margin="-2,-2,-2,-2">
<Border.Background>
<SolidColorBrush Color="{DynamicResource DisabledColor}"/>
</Border.Background>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" TargetName="border" Value="Visible"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用完之后运行发现界面不对,点击分组标题后列表内容没有显示???

查找原因
自己想了一下,原因不明,无奈自己对WPF实现只了解一点,于是网上搜索ItemsPresenter empty,找到第一条网页ItemsPresenter + ItemsPanelTemplate vs Panel marked with IsItemsHost,进去后发现他提出了一个问题,就是在分组时如何取ItemsPresenter,发现Reflector工具可以看到以下代码:
代码
internal static ItemsPresenter FromGroupItem(GroupItem groupItem)
{
if (groupItem == null)
{
return null;
}
Visual parent = VisualTreeHelper.GetParent(groupItem) as Visual;
if (parent == null)
{
return null;
}
return (VisualTreeHelper.GetParent(parent) as ItemsPresenter);
}
这个帖子上面也解释了为什么这么设计,我就不再重复了,原来在分组时对控件样式有要求,那就是控件样式必须存在ItemsPresenter。
确认原因
使用《WPF - Visual调试工具Snoop》工具查看一下,发现GroupItem下的ItemsPresenter是空的

切换回不使用样式再看看,发现在GroupItem之上有一个ItemsPresenter,而应用上面样式之后就没有了,果然就是样式文件的控件模板缺少ItemsPresenter的原因。

解决问题
原因知道了,解决问题也就非常简单了,修改样式表,主要就是把
<StackPanel Margin="2" IsItemsHost="true"/>
该为
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
修改后再次运行,界面正确,如下:

更多内容:
开源信息系统开发平台之OpenExpressApp框架.pdf
欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]
WPF - Group分组对ListBox等列表样式的约束的更多相关文章
- C# WPF DataGrid 分组(Group)
原文:C# WPF DataGrid 分组(Group) 效果如图,每个列的名字可以自定义.我随便用了”File”和”Attachment Name”. 在Window的Resources里面设置S ...
- WPF中修改ListBox项的样式病修改选中项的背景颜色
最终效果: 1 <ListBox Name="cmb"> 2 <!--修改颜色--> 3 <ListBox.Resources> 4 <! ...
- signalr中Group 分组群发消息的简单使用
前一段时间写了几篇关于signalr的文章 1.MVC中使用signalR入门教程 2.mvc中signalr实现一对一的聊天 3.Xamarin android中使用signalr实现即时通讯 在平 ...
- WPF 4 DataGrid 控件(自定义样式篇)
原文:WPF 4 DataGrid 控件(自定义样式篇) 在<WPF 4 DataGrid 控件(基本功能篇)>中我们已经学习了DataGrid 的基本功能及使用方法.本篇将继续 ...
- 浅析mongodb中group分组
这篇文章主要介绍了浅析mongodb中group分组的实现方法及示例,非常的简单实用,有需要的小伙伴可以参考下. group做的聚合有些复杂.先选定分组所依据的键,此后MongoDB就会将集合依据选定 ...
- CSS3初学篇章_5(背景样式/列表样式/过渡动画)
背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...
- WPF后台设置xaml控件的样式System.Windows.Style
WPF后台设置xaml控件的样式System.Windows.Style 摘-自 :感谢 作者: IT小兵 http://3w.suchso.com/projecteac-tual/wpf-zhi ...
- WPF如何用TreeView制作好友列表、播放列表
WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...
- SharePoint 2010 修改默认列表样式
SharePoint 2010 修改默认列表样式 :可以通过修改 下面两个全局配置进行修改.(未完..更新中...) C:\Program Files\Common Files\Microsoft ...
随机推荐
- jquery-8 jquery如何处理css样式
jquery-8 jquery如何处理css样式 一.总结 一句话总结: 1.如何获取网页的三个高? 1)可视区域的高$(window).height(); 2)文档总高度$(document).h ...
- TF-IDF计算方法和基于图迭代的TextRank
文本处理方法概述 说明:本篇以实践为主,理论部分会尽量给出参考链接 摘要: 1.分词 2.关键词提取 3.主题模型(LDA/TWE) 4.词的两种表现形式(词袋模型和分布式词向量) 5.关于文本的特征 ...
- Android JNI编程(八)——体验AS2.2.2编写Jni程序、Java调C、C调Java函数、将C代码中的Log打印至Logcat
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 不得不说在AS2.2以上的版本进行开发就一个字——爽,在2.0上使用jni出 ...
- 最新国内外可用SVN托管仓库有哪些
最新国内外可用SVN托管仓库哪些 一.总结 一句话总结:用SVNBucket和SourceForge 二.最新国内外可用SVN托管仓库推荐 这几年很多SVN托管平台都基本不维护或者直接关闭了,我翻遍了 ...
- 强大的 function adapters
void printElem(int elem, const char* prefix){ cout << prefix << elem << endl; } fo ...
- UE4的JSON读写方式<二>
声明:所有权利保留. 转载必须说明出处:http://blog.csdn.net/cartzhang/article/details/43794409 Json的Writer博客地址: http:// ...
- 【t042】炮击坦克
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在一个坐标轴上,有M辆坦克,第i辆坦克在时刻0处于pos[i](pos[i]>0),speed[ ...
- matlab 机器学习相关函数、api
matlab 对数据集的默认组织方式是,X∈Rd×N d:行数,表示特征向量的长度: N:列数,表示样本的数目: 1. 模型.预测.mse % 加载 matlab 内置数据到内存 X = abalon ...
- erlang tcp发包速度测试
http://blog.sina.com.cn/s/blog_96b8a1540101317m.html 这段时间我们的项目遇到广播包的一些性能问题,想起之前看到yufeng老大提到的1s广播40K包 ...
- 谷歌 AI 中国中心成立,人工智能势不可挡?
昨日,谷歌在上海举办了一年一度的Google中国开发者大会.在本届大会上,谷歌云首席科学家李飞飞宣布了一个重磅消息,即在北京将成立谷歌AI中国中心.对于这个即将成立的AI中心谷歌寄予厚望,希望与中国本 ...