需求
最近在做的一个小工具中用到了ListView来显示一些数据。但是ListView默认的样式不太符合个人的审美,于是想修改ListView子项的各种效果。
尝试过程
阶段1 自己摸索
按照以往对于控件样式修改的流程来说,应该是选择这个控件,然后创建它的模板,通过修改模板来达到效果。
例如ListBox中选择项的修改方式就是:
可是ListView的结构并不是这样的,虽然在XAML代码中设置了ListView.View属性,但是ListView内部并没有一个ListViewItem可以让我们来编辑模板。
阶段2 查找别人的解决方案
既然按照自己以往的处理方式并不能解决问题,那么就只好去搜索一下如何修改了。
在国内外的搜索引擎上都尝试过搜索了,能看到最常用的处理方式是:
<ListView x:Name="listView2"><ListView.Resources><Style TargetType="{x:Type ListViewItem}"><Style.Triggers><Trigger Property="IsSelected" Value="true"><Setter Property="Background" Value="Orange" /><Setter Property="Foreground" Value="White" /><Setter Property="BorderBrush" Value="Blue" /><Setter Property="BorderThickness" Value="10"/></Trigger><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="Pink" /><Setter Property="Foreground" Value="Black" /><Setter Property="BorderBrush" Value="Purple" /><Setter Property="BorderThickness" Value="5"/></Trigger></Style.Triggers></Style></ListView.Resources><ListView.View><GridView><GridViewColumn Header="ColumnA" DisplayMemberBinding="{Binding Path=A}"/><GridViewColumn Header="ColumnB" DisplayMemberBinding="{Binding Path=B}"/><GridViewColumn Header="ColumnC" DisplayMemberBinding="{Binding Path=C}"/><GridViewColumn Header="ColumnD" DisplayMemberBinding="{Binding Path=D}"/></GridView></ListView.View></ListView>
(上述的Style也可以设置给ListView.ItemContainerStyle属性)
这样做虽然起效了,可是只能修改一部分内容的样式,其他部分(例如中间有一层渐变色)却无从修改:
因此这个方法并不能达到我的要求。
阶段3 再次摸索(解决问题)
在继续尝试对控件进行创建模板的时候,我突然发现一个选项:
点击后,会在ListView中添加一个ListViewItem,然后对着这个ListViewItem右键就可以创建模板了!
那这样不就可以修改模板到自己想要的样式,然后设置给ListView.ItemContainerStyle属性了吗?
<ListView x:Name="listView3" ItemContainerStyle="{DynamicResource ListViewItemStyle1}"><ListView.View><GridView><GridViewColumn Header="ColumnA" DisplayMemberBinding="{Binding Path=A}"/><GridViewColumn Header="ColumnB" DisplayMemberBinding="{Binding Path=B}"/><GridViewColumn Header="ColumnC" DisplayMemberBinding="{Binding Path=C}"/><GridViewColumn Header="ColumnD" DisplayMemberBinding="{Binding Path=D}"/></GridView></ListView.View></ListView>
然而事情并没有那么顺利,最终程序显示的效果出现了问题:
每行的样式确实是变了,但每行显示的内容却出现了问题,与我们想要的表格是不一样的,只显示了一个内容。
这又是为什么呢?
于是只好再去搜索引擎上查找,看有没有能解决的方案。最终看到了这样一个帖子:
这样就明白了!ListViewItem内部应该使用GridViewRowPresenter组件,而并非是创建副本时给的ContentPresenter!
只要在模板中把控件改变一下就好了!
原本是:
<ControlTemplate TargetType="{x:Type ListViewItem}"><Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"><ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border></ControlTemplate>
修改为:
<ControlTemplate TargetType="{x:Type ListViewItem}"><Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"><GridViewRowPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border></ControlTemplate>
再次运行程序:
收工!
