原文:
在做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 = " 1 " SnapsToDevicePixels = " true " X1 = " 0 " X2 = " 1 " Stretch = " Fill " StrokeThickness = " 1 " /> </ 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 = " 0 " /> < GradientStop Color = " {DynamicResource SecondaryColor} " Offset = " 1 " /> </ LinearGradientBrush > </ Setter.Value > </ Setter > < Setter Property = " BorderThickness " Value = " 1 " /> < 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 = " 1 " CornerRadius = " 4,4,4,4 " > < Grid > < ScrollViewer Padding = " {TemplateBinding Padding} " Focusable = " false " x:Name = " scrollViewer " > < StackPanel Margin = " 2 " 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,发现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。
确认原因
使用工具查看一下,发现GroupItem下的ItemsPresenter是空的
切换回不使用样式再看看,发现在GroupItem之上有一个ItemsPresenter,而应用上面样式之后就没有了,果然就是样式文件的控件模板缺少ItemsPresenter的原因。
解决问题
原因知道了,解决问题也就非常简单了,修改样式表,主要就是把
<StackPanel Margin="2" IsItemsHost="true"/>
该为
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
修改后再次运行,界面正确,如下:
更多内容:
欢迎转载,转载请注明:转载自 [ ]