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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF:ListView自定义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}">
...
答案

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>
另一答案

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, Relat

以上是关于WPF:ListView自定义scrollviewer导致列标题消失的主要内容,如果未能解决你的问题,请参考以下文章

求助scrollview嵌套viewpager 放listview 不能滑动

WPF自定义控件与样式-ScrollViewer与ListBox自定义样式

WPF自定义控件之仿Win8滚动条--ScrollViewer

WPF 自定义滑动ScrollViewer

wpf listview 换行

WPF 自定义ScrollViwer