我可以在基本(非GridView)模式下轻松“隐式”设置ListView样式,但是我在GridView模式下隐式设置ListView样式的尝试却失败了。下面的工作原理是因为我明确设置了第二个ListView的Style和ItemContainerStyle。如果删除这两个设置,则第二个ListView不会像第一个那样进行隐式设置。似乎基本的ListView需要ContentPresenter,而GridView ListView需要GridViewRowPresenter。
我在这里跑进WPF砖墙吗?这甚至可能吗?如果没有,它会使创建应用程序外观不那么健壮,因为现在您的用户必须知道在GridView模式下显示的ListViews上显式设置Style和ItemContainerStyle。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="ListView">
<Setter Property="Background" Value="Lime"/>
</Style>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<ContentPresenter x:Name="ContentHost" Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Static GridView.GridViewStyleKey}"
TargetType="{x:Type ListView}">
<Setter Property="Background" Value="Lime"/>
</Style>
<Style x:Key="{x:Static GridView.GridViewItemContainerStyleKey}"
TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Yellow"/>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="_listView1">
<system:String>Item 1</system:String>
<system:String>Item 2</system:String>
<system:String>Item 3</system:String>
</ListView>
<ListView x:Name="_listView2" Grid.Column="1"
Style="{StaticResource {x:Static GridView.GridViewStyleKey}}"
ItemContainerStyle="{StaticResource {x:Static GridView.GridViewItemContainerStyleKey}}">
<ListView.View>
<GridView>
<GridViewColumn Header="Date"/>
<GridViewColumn Header="Day of Week" DisplayMemberBinding="{Binding DayOfWeek}" />
<GridViewColumn Header="Year" DisplayMemberBinding="{Binding Year}" />
</GridView>
</ListView.View>
<system:DateTime>1/1/2010</system:DateTime>
<system:DateTime>1/1/2011</system:DateTime>
<system:DateTime>1/1/2012</system:DateTime>
</ListView>
</Grid>
</Window>
答案 0 :(得分:4)
我遇到了与你上面描述的相同的奇怪/棘手的问题,然后遇到了一篇博文,其中提出了一个简洁的小黑客/修复方法,它似乎提供了你所追求的行为。如果链接死亡,重复要点。
如果您想要使用ListView
覆盖视图并使用GridViews
,您已经描述了ListView
样式的奇怪要求;基本ContentPresenter
需要GridView ListView needs
,GridViewRowPresenter
和Setter
。
海报设法通过在他的风格中包括两位演示者并使用ContentPresenter
仅在需要时显示ControlTemplate
来解决这个问题。
所以你的<ControlTemplate TargetType="{x:Type ListBoxItem}">
<!-- Pair of presenters -->
<Grid>
<GridViewRowPresenter x:Name="gridrowPresenter"
Content="{TemplateBinding Property=ContentControl.Content}"/>
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Property=ContentControl.Content}" Visibility="Collapsed"/>
</Grid>
<!-- Visibility Controlling Setter -->
<ControlTemplate.Triggers>
<Trigger Property="GridView.ColumnCollection" Value="{x:Null}">
<Setter TargetName="contentPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
可以按照这些方式实现某些功能(根据需要添加额外的样式属性):
GridViewRowPresenter
样式中存在ContentPresenter
和ContentPresenter
,但Visibility="Collapsed"
被隐藏(Trigger
)。
巧妙的诀窍是在GridView.ColumnCollection
上使用GridViewRowPresenter
;如果此值为null(在ContentPresenter
没有内容时发生),则ListView
将变为可见,正确显示您的正常GridViewRowPresenter
内容。 GridView
没有内容,因此不会显示任何有冲突的视觉效果。
如果ContentPresenter
包含内容,则会显示(提供正确的行格式),{{1}}将保持隐藏状态。
原创博客文章:http://www.steelyeyedview.com/2010/03/contentpresenter-gridviewrowpresenter.html