【问题标题】:Is it possible to implicitly style a WPF ListView in GridView mode?是否可以在 GridView 模式下隐式设置 WPF ListView 的样式?
【发布时间】:2013-02-16 21:46:39
【问题描述】:

我可以轻松地在基本(非 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>

【问题讨论】:

  • 这可能有点晚了,但我试图回答另一个问题,并找到了一个可能有用的解决方法:stackoverflow.com/questions/18700352/…
  • 将其转换为答案,我会这样标记。谢谢!
  • 完成,很高兴它有用!

标签: wpf styles skinning


【解决方案1】:

我遇到了与您在上面描述的相同的奇怪/棘手问题,并遇到了一篇博客文章,其中建议了一个简洁的小技巧/修复,这似乎提供了您所追求的行为。重复要点以防链接失效。

如果你想用GridViews 覆盖视图,你已经描述了ListView 样式的奇怪要求;一个基本的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>

GridViewRowPresenterContentPresenter 都出现在样式中,但 ContentPresenter 是隐藏的 (Visibility="Collapsed")。

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

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

原博文:http://www.steelyeyedview.com/2010/03/contentpresenter-gridviewrowpresenter.html

【讨论】:

    猜你喜欢
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2014-05-12
    相关资源
    最近更新 更多