是否可以在GridView模式下隐式设置WPF ListView的样式



我可以在基本(非GridView)模式下轻松地"隐式"设置ListView的样式,但我在GridView模式下隐式设置ListView样式的尝试却失败了。以下操作之所以有效,是因为我明确设置了第二个ListView的Style和ItemContainerStyle。如果删除这两个设置,第二个ListView就不会像第一个那样得到隐式样式。基本的ListView似乎需要一个ContentPresenter,而GridView ListView则需要一个GridViewRowPresenter。

我是不是撞上了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>

我遇到了与您上面描述的相同的奇怪/棘手的问题,并遇到了一篇博客文章,其中建议了一个巧妙的小破解/修复,似乎可以提供您想要的行为。要点会重复,以防链接失效。

如果您想使用和使用GridViews来覆盖视图,您已经描述了ListView样式的奇怪要求;基本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,但隐藏了ContentPresenterVisibility="Collapsed")。

巧妙的技巧是在GridView.ColumnCollection上使用Trigger;如果该值为null(当GridViewRowPresenter没有内容时发生),则ContentPresenter将可见,从而正确显示正常的ListView内容)。GridViewRowPresenter将没有任何内容,因此不会显示任何冲突的视觉效果。

如果GridView有内容,它将被显示(提供正确的行格式),而ContentPresenter将保持隐藏。

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

相关内容

  • 没有找到相关文章

最新更新