博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF - Group分组对ListBox等列表样式的约束
阅读量:5983 次
发布时间:2019-06-20

本文共 4823 字,大约阅读时间需要 16 分钟。

原文:

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

ListBox增加分组2009120409170926.jpg

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

  1. 给列表控件增加分组样式
    ContractedBlock.gif
    ExpandedBlockStart.gif
    代码
     
    <
    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);
  2. 给数据增加分组

    ContractedBlock.gif
    ExpandedBlockStart.gif
    代码
     
    <
    UserControl.Resources
    >
    <
    CollectionViewSource Source
    =
    "
    {x:Static oea:ApplicationModel.DefaultBusinessObjectInfos}
    "
    x:Key
    =
    "
    cvs
    "
    >
    <
    CollectionViewSource.GroupDescriptions
    >
    <
    PropertyGroupDescription PropertyName
    =
    "
    Catalog
    "
    />
    </
    CollectionViewSource.GroupDescriptions
    >
    </
    CollectionViewSource
    >
    </
    UserControl.Resources
    >

使用ListBox样式后

  用了别人的一个ListBox样式文件,样式如下:

ContractedBlock.gif
ExpandedBlockStart.gif
代码
 
<
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
>

用完之后运行发现界面不对,点击分组标题后列表内容没有显示???

  2009120409253743.jpg

查找原因

  自己想了一下,原因不明,无奈自己对WPF实现只了解一点,于是网上搜索ItemsPresenter empty,找到第一条网页,进去后发现他提出了一个问题,就是在分组时如何取ItemsPresenter,发现Reflector工具可以看到以下代码:

 
ContractedBlock.gif
ExpandedBlockStart.gif
代码
 
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是空的

2009120409293390.jpg

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

2009120409335788.jpg

解决问题

原因知道了,解决问题也就非常简单了,修改样式表,主要就是把

<StackPanel Margin="2" IsItemsHost="true"/>

该为

<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"

修改后再次运行,界面正确,如下:

2009120409451834.jpg

 

更多内容:productView-pdf_46x35.gif

 

 

欢迎转载,转载请注明:转载自 [ ]

你可能感兴趣的文章
python 常用模块
查看>>
confluence使用问题总结
查看>>
文章分享:Android四大组件详解
查看>>
Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp
查看>>
自定义ActionBar高分辨率下左边缺一块的解决方案
查看>>
OSPF、EIGRP路由汇总
查看>>
ISCSI安装配置
查看>>
京东金融大数据竞赛猪脸识别(2)- 图像特征提取之一
查看>>
jstl 一些表达式的用法
查看>>
Zookeeper实战之单机模式
查看>>
同步,异步,并行和串行之间区别
查看>>
Hadoop2.5.2 HA主备切换失败的解决办法
查看>>
借助开源工具高效完成Java应用的运行分析
查看>>
深入浅出DDoS***
查看>>
MySQL 基础常用命令
查看>>
32位系统安装64位windows 8
查看>>
hive ETL之电商零售行业-推荐系统sql
查看>>
Debian安装hadoop[大象]-1.2.1
查看>>
BREW中的调试信息
查看>>
Python学习笔记(1~26页)(《Head First Python》)
查看>>