原文:WPF - Group分组对ListBox等列表样式的约束

  在做WPF主题支持时,出现一个分组引起的莫名错误,可是折腾了我一番。在没有使用样式时,列表分组很正常,使用了别人写的ListBox列表样式后,发现GroupItem分组区没有内容,是空的,本篇把这一问题的解决过程给大家说一下,做主题时可以注意分组对列表样式的限制了。

ListBox增加分组

  WPF为ItemsControl提供很多的样式扩展,要想实现列表分组也很简单,只需要做以下几步就可以了:

  1. 给列表控件增加分组样式

    代码

    <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);
  2. 给数据增加分组

    代码

    <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等列表样式的约束的更多相关文章

  1. C# WPF DataGrid 分组(Group)

    原文:C# WPF DataGrid 分组(Group) 效果如图,每个列的名字可以自定义.我随便用了”File”和”Attachment Name”.  在Window的Resources里面设置S ...

  2. WPF中修改ListBox项的样式病修改选中项的背景颜色

    最终效果: 1 <ListBox Name="cmb"> 2 <!--修改颜色--> 3 <ListBox.Resources> 4 <! ...

  3. signalr中Group 分组群发消息的简单使用

    前一段时间写了几篇关于signalr的文章 1.MVC中使用signalR入门教程 2.mvc中signalr实现一对一的聊天 3.Xamarin android中使用signalr实现即时通讯 在平 ...

  4. WPF 4 DataGrid 控件(自定义样式篇)

    原文:WPF 4 DataGrid 控件(自定义样式篇)      在<WPF 4 DataGrid 控件(基本功能篇)>中我们已经学习了DataGrid 的基本功能及使用方法.本篇将继续 ...

  5. 浅析mongodb中group分组

    这篇文章主要介绍了浅析mongodb中group分组的实现方法及示例,非常的简单实用,有需要的小伙伴可以参考下. group做的聚合有些复杂.先选定分组所依据的键,此后MongoDB就会将集合依据选定 ...

  6. CSS3初学篇章_5(背景样式/列表样式/过渡动画)

    背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...

  7. WPF后台设置xaml控件的样式System.Windows.Style

    WPF后台设置xaml控件的样式System.Windows.Style 摘-自 :感谢 作者: IT小兵   http://3w.suchso.com/projecteac-tual/wpf-zhi ...

  8. WPF如何用TreeView制作好友列表、播放列表

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

  9. SharePoint 2010 修改默认列表样式

    SharePoint 2010  修改默认列表样式 :可以通过修改 下面两个全局配置进行修改.(未完..更新中...)  C:\Program Files\Common Files\Microsoft ...

随机推荐

  1. [Docker] Download and Remove Docker Images

    Learn the basics of downloading and pulling Docker images from Docker Hub. Learn the difference betw ...

  2. window.onload,<body onload="function()">, document.onreadystatechange, httpRequest.onreadystatechang 分类: C1_HTML/JS/JQUERY 2014-08-06 16:47 558人阅读 评论(0) 收藏

    部分内容参考:http://www.aspbc.com/tech/showtech.asp?id=1256 在开发的过程中,经常使用window.onload和body onload两种,很少使用do ...

  3. #308 (div.2) B. Vanya and Books

    1.题目描写叙述:点击打开链接 2.解题思路:本题要求统计数位的个数,简单的试验一下发现有例如以下规律:一个n位数的个数有9*(10^n)个.因此全部n位数的数位是n*9*(10^n)个.因此能够利用 ...

  4. c++ 成员函数指针

    C++中,成员指针是最为复杂的语法结构.但在事件驱动和多线程应用中被广泛用于调用回叫函数.在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数.在这样的应用中,如果不用成员指针,编程是非常困难 ...

  5. java判断字符串是否为数字

    我们在做安卓开发中,一定会遇到判断某字符串是否是数字的问题,本文使用正则表达式可以很方便的判断出来,希望本文对安卓开发者有所帮助.   1 public boolean isNumeric(Strin ...

  6. ios开发不能不知的动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入、和使用、.js文件传输加解密

    JSPatch ios开发不能不知的动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入.和使用..js文件传输加解密 ios开发面临审核周期长,修复bug延迟等让人无奈的问题,所以 ...

  7. 【转】A* A星 算法 C语言 实现代码

    http://blog.csdn.net/shanshanpt/article/details/8977512 关于A*算法,很早就想写点什么,可是貌似天天在忙活着什么,可事实又没有做什么,真是浮躁啊 ...

  8. TOP 10 ONLINE COMPILER

    Top 10 Online Compilers +1338 Tweet Share106 Share Pin 444 Shares Online compilers are one type of t ...

  9. Java 中StringBuffer与StringBuilder区别(转)及String类的一些基本操作代码

    String 字符串常量StringBuffer 字符串变量(线程安全)  多个线程访问时,不会产生问题(Synchronized)StringBuilder 字符串变量(非线程安全) 多个线程访问时 ...

  10. 浅谈CAS(Compare and Swap) 原理

    浅谈CAS原理java并发编程也研究了一段时间了,对CAS的原理总是不太理解,今天再研究了一下,记录一些自己的理解.    说到CAS,再java中的某些情况下,甚至jdk1.5以后的大多数情况,并发 ...