WPF:ListView自定义scrollviewer导致列标题消失

时间:2018-10-09 10:37:47

标签: c# wpf listview styles scrollviewer

我一直在为ListView编写自定义ScrollViewer样式。应用样式后(请参见下面的代码),它将从视图中删除“列标题”,仅将项目保留在列表中。

我似乎只有:

  • 没有自定义滚动查看器的工作标题
  • 没有标题的自定义滚动查看器

我不知道为什么会这样。我应该怎么做才能使它正常工作?

编辑:

相信,这是因为我以自己的风格(如下)定义了一个空的ItemsPresenter,但这是其他人似乎正在做/推荐的事情。

>

列表视图样式

<Style x:Key="StandardListView" TargetType="{x:Type ListView}">
    <Setter Property="Background" Value="{DynamicResource TransparentWhite}" />
    <Setter Property="Foreground" Value="{DynamicResource TextParagraphLightGreyP1}" />
    <Setter Property="BorderBrush" Value="{DynamicResource ControlOutlineDisabled}" />
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListView">
                <ScrollViewer Style="{DynamicResource StandardScrollViewer}">
                    <ItemsPresenter >
                    </ItemsPresenter>
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

自定义滚动查看器样式

<Style x:Key="StandardScrollViewer" TargetType="{x:Type ScrollViewer}">
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="BorderBrush" Value="{DynamicResource BackgroundGreyLevel2}" />
        <Setter Property="Background" Value="{DynamicResource CollectionControlBackgroundGradient}" />
        <Setter Property="VerticalScrollBarVisibility" Value="Auto"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <ScrollContentPresenter Grid.ColumnSpan="2" Grid.RowSpan="2"/>
                        <ScrollBar Name="PART_VerticalScrollBar"
                                   HorizontalAlignment="Right"
                                   Opacity="0.5" 
                                   Grid.Column="1"
                                   Value="{TemplateBinding VerticalOffset}"
                                   Maximum="{TemplateBinding ScrollableHeight}"
                                   ViewportSize="{TemplateBinding ViewportHeight}"
                                   Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
                        <ScrollBar Name="PART_HorizontalScrollBar"
                                   VerticalAlignment="Bottom"
                                   Orientation="Horizontal"
                                   Opacity="0.5"
                                   Grid.Row="1"
                                   Value="{TemplateBinding HorizontalOffset}"
                                   Maximum="{TemplateBinding ScrollableWidth}"
                                   ViewportSize="{TemplateBinding ViewportWidth}"
                                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

视图中的列表

<ListView x:Name="Licences" Margin="2,20,2,25" Style="{DynamicResource StandardListView}">
...

2 个答案:

答案 0 :(得分:1)

GridView标头是ScrollViewer的一部分。该模板应该可以工作:

<ControlTemplate TargetType="ListView">
    <ScrollViewer Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
        <ItemsPresenter >
        </ItemsPresenter>
    </ScrollViewer>
</ControlTemplate>

如果要使用带有标题的自定义ScrollViewer,则需要创建一个。您可以从下面的默认GridView.GridViewScrollViewerStyleKey样式开始,然后根据需要进行修改:

<Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="{x:Type ScrollViewer}">
    <Setter Property="UIElement.Focusable" Value="false"/>
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid Background="{TemplateBinding Control.Background}" SnapsToDevicePixels="true">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <DockPanel Margin="{TemplateBinding Control.Padding}">
                        <ScrollViewer DockPanel.Dock="Top" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
                            Focusable="false">
                            <GridViewHeaderRowPresenter Margin="2,0,2,0" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
                                            ColumnHeaderContainerStyle="{Binding Path=TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}"
                                            ColumnHeaderTemplate="{Binding Path=TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                            ColumnHeaderTemplateSelector="{Binding Path=TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
                                            ColumnHeaderStringFormat="{Binding Path=TemplatedParent.View.ColumnHeaderStringFormat, RelativeSource={RelativeSource TemplatedParent}}"
                                            AllowsColumnReorder="{Binding Path=TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
                                            ColumnHeaderContextMenu="{Binding Path=TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
                                            ColumnHeaderToolTip="{Binding Path=TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}">
                                <GridViewRowPresenterBase.Columns>
                                    <Binding Path="TemplatedParent.View.Columns" RelativeSource="{RelativeSource TemplatedParent}"/>
                                </GridViewRowPresenterBase.Columns>
                            </GridViewHeaderRowPresenter>
                        </ScrollViewer>
                        <ScrollContentPresenter Name="PART_ScrollContentPresenter" KeyboardNavigation.DirectionalNavigation="Local"
                                      Content="{TemplateBinding ContentControl.Content}"
                                      ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                      CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
                                      SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
                    </DockPanel>
                    <ScrollBar Name="PART_HorizontalScrollBar" Orientation="Horizontal" Grid.Row="1" Minimum="0.0"
                       Maximum="{TemplateBinding ScrollViewer.ScrollableWidth}"
                       ViewportSize="{TemplateBinding ScrollViewer.ViewportWidth}"
                       Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}" Cursor="Arrow"
                       Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                    <ScrollBar Name="PART_VerticalScrollBar" Orientation="Vertical" Grid.Column="1" Minimum="0.0"
                       Maximum="{TemplateBinding ScrollViewer.ScrollableHeight}"
                       ViewportSize="{TemplateBinding ScrollViewer.ViewportHeight}"
                       Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}" Cursor="Arrow"
                       Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                    <DockPanel Grid.Column="1" Grid.Row="1" LastChildFill="false"
                       Background="{Binding Path=Background, ElementName=PART_VerticalScrollBar}">
                        <Rectangle DockPanel.Dock="Left" Width="1" Fill="White"
                         Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}"/>
                        <Rectangle DockPanel.Dock="Top" Height="1" Fill="White"
                         Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}"/>
                    </DockPanel>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

答案 1 :(得分:0)

mm8的答案可以解决问题。从本质上来说,似乎我不正确地将GridViewHeaderRowPresenter放置在ListView样式中,而实际上应将其放置在ScrollViewer样式中,如下所示:

   <Style x:Key="StandardScrollViewer" TargetType="{x:Type ScrollViewer}">
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="BorderBrush" Value="{DynamicResource BackgroundGreyLevel2}" />
        <Setter Property="Background" Value="{DynamicResource CollectionControlBackgroundGradient}" />
        <Setter Property="VerticalScrollBarVisibility" Value="Hidden"></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <DockPanel Margin="{TemplateBinding Padding}" Grid.ColumnSpan="2" Grid.RowSpan="2">
                            <ScrollViewer DockPanel.Dock="Top" Grid.ColumnSpan="2" Grid.RowSpan="2" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Focusable="False">
                                <GridViewHeaderRowPresenter x:Name="GridViewHeaderRowPresenter" Margin="2,0,2,0" Columns="{Binding Path=TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContainerStyle="{Binding Path=TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderTemplate="{Binding Path=TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderTemplateSelector="{Binding Path=TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}" AllowsColumnReorder="{Binding Path=TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContextMenu="{Binding Path=TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderToolTip="{Binding Path=TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </ScrollViewer>
                            <ScrollContentPresenter Name="PART_ScrollContentPresenter" KeyboardNavigation.DirectionalNavigation="Local" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.RowSpan="2"/>
                        </DockPanel>
                        <ScrollBar Name="PART_VerticalScrollBar"
                                   HorizontalAlignment="Right" 
                                   Grid.Column="1"
                                   Grid.Row="0"
                                   MaxHeight="{TemplateBinding ViewportHeight}"

                                   VerticalAlignment="Stretch"
                                   Value="{TemplateBinding VerticalOffset}"
                                   Maximum="{TemplateBinding ScrollableHeight}"
                                   ViewportSize="{TemplateBinding ViewportHeight}"
                                   Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
                        <ScrollBar Name="PART_HorizontalScrollBar"
                                   VerticalAlignment="Bottom"
                                   Orientation="Horizontal"
                                   Grid.Row="1"
                                   Value="{TemplateBinding HorizontalOffset}"
                                   Maximum="{TemplateBinding ScrollableWidth}"
                                   ViewportSize="{TemplateBinding ViewportWidth}"
                                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

然后,我更新了ListView样式,如下所示:

<Style x:Key="StandardListView" TargetType="{x:Type ListView}">
    <Setter Property="Background" Value="{DynamicResource TransparentWhite}" />
    <Setter Property="Foreground" Value="{DynamicResource TextParagraphLightGreyP1}" />
    <Setter Property="BorderBrush" Value="{DynamicResource ControlOutlineDisabled}" />
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListView">
                <ScrollViewer Style="{DynamicResource StandardScrollViewer}">
                    <DockPanel>
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </DockPanel>
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>