2013-02-16 50 views
4

我可以在基本(非GridView)模式下轻松“隐式”设计ListView,但是我尝试在GridView模式下隐式设置ListView的方式失败了。下面的作品是因为我明确地设置了第二个ListView的Style和ItemContainerStyle。如果你删除了这两个设置,第二个ListView并不像第一个那样被隐式地设计。看起来基本的ListView需要一个ContentPresenter,而一个GridView ListView需要一个GridViewRowPresenter。是否可以在GridView模式下隐式设置WPF ListView?

我在这里跑到一个WPF砖墙吗?这甚至有可能吗?如果没有,它会使创建应用程序皮肤的稳健性下降,因为现在用户必须知道在GridView模式下显示的ListView上显式设置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

这可能是一个有点晚来,但我试图回答另一个问题时,发现可能是有益的一种变通方法:http://stackoverflow.com/questions/18700352/listviewitem -override-default-style-break-gridviews/18775166#18775166 – Chris 2013-09-12 22:16:08

+0

将其转换为答案,我会将其标记为这样。谢谢! – 2013-09-13 01:05:47

+0

完成,很高兴它很有用! – Chris 2013-09-13 10:24:36

回答

4

我遇到同样的奇/棘手的问题,因为你上面描述,跑进一个博客贴子,提出了一个整洁的小黑客/修复,这似乎提供你以后的行为。如果链接消失,重复要点。

您已经描述了ListView样式的奇怪要求,如果您要覆盖视图并使用GridViews;基本的ListView需要ContentPresenterGridView ListView needsGridViewRowPresenter

海报设法通过包括他的风格中同时主持人,并使用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> 

两个GridViewRowPresenterContentPresenter存在于风格,但ContentPresenter是隐藏的(Visibility="Collapsed")。

巧妙的技巧是使用TriggerGridView.ColumnCollection;如果此值为空(当GridViewRowPresenter没有内容时发生),则ContentPresenter将变为可见,正确显示正常ListView内容)。 GridViewRowPresenter将没有内容,所以它不会显示任何冲突的视觉效果。

如果GridView包含内容,它将显示(提供正确的行格式),并且ContentPresenter将保持隐藏状态。

原始博客条目:http://www.steelyeyedview.com/2010/03/contentpresenter-gridviewrowpresenter.html

相关问题