使 XAML 列表视图 header 具有完整的滚动条

making the XAML list view header sticky with full scroll bar

我有一个列表视图,其中有一个 header 模板

<Grid Margin="70,0,0,0">
  <ListView x:Name="LanguagesListView"  DataContext="{x:Bind ViewModel}" Grid.Row="2" Style="{StaticResource LanguagesListViewStyle}" ItemsSource="{x:Bind ViewModel.Languages}" SelectedItem="{x:Bind ViewModel.SelectedLanguage, Mode=TwoWay}" HorizontalAlignment="Stretch" >              
            <ListView.HeaderTemplate>
                <DataTemplate>
                    <Grid Margin="0,0,70,0" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <TextBlock Grid.Row="0" Text="{Binding Strings.ui_language_setting}" Style="{ThemeResource H1TextBlockStyle}" TextTrimming="CharacterEllipsis" TextWrapping="WrapWholeWords"/>
                        <TextBlock Grid.Row="1" Text="{Binding Strings.ui_language_copy}" Style="{ThemeResource BodyTitleTextBlockStyle}" Foreground="{StaticResource Gray9Brush}" TextWrapping="WrapWholeWords" HorizontalAlignment="Left" Margin="0,10,0,30" TextTrimming="CharacterEllipsis"/>
                    </Grid>
                </DataTemplate>
            </ListView.HeaderTemplate>
  </ListView>
</Grid>

列表视图的样式是

<Style x:Key="LanguagesListViewStyle" TargetType="ListView">
        <Setter Property="TabNavigation" Value="Local" />
        <Setter Property="Padding" Value="0,0,50,55" />
        <Setter Property="IsItemClickEnabled" Value="True" />
        <Setter Property="ItemContainerStyle" Value="{StaticResource LanguagesListViewItemContainerStyle}" />
        <Setter Property="ItemTemplate" Value="{StaticResource LanguagesListViewItemTemplate}" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
        <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
        <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
        <Setter Property="ScrollViewer.IsHorizontalRailEnabled" Value="False" />
        <Setter Property="ScrollViewer.IsHorizontalScrollChainingEnabled" Value="False" />
        <Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True" />
        <Setter Property="ScrollViewer.IsVerticalScrollChainingEnabled" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListView">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" 
                        Background="{TemplateBinding Background}" 
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>

                            <ContentControl Content="{TemplateBinding Header}"
                                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                                            ContentTransitions="{TemplateBinding HeaderTransitions}"/>

                            <ScrollViewer x:Name="ScrollViewer"
                                      Grid.Row="1"
                                    TabNavigation="{TemplateBinding TabNavigation}"
                                    HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                    HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                    IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
                                    VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                    VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                    IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
                                    IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                    IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                    ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"
                                    IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                    BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
                                    AutomationProperties.AccessibilityView="Raw">
                                <ItemsPresenter 
                                            Footer="{TemplateBinding Footer}"
                                            FooterTemplate="{TemplateBinding FooterTemplate}"
                                            FooterTransitions="{TemplateBinding FooterTransitions}"
                                           Padding="{TemplateBinding Padding}" />
                            </ScrollViewer>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我的目标是使列表视图的 Header 保持粘性,但我希望列表视图的滚动查看器也能跨越 header 区域。当前滚动条出现在 header.

下方

我想让滚动查看器位于右上角,同时保持 header 粘性。

感谢任何帮助。

making the XAML list view header sticky with full scroll bar

问题是您将 header 放在了 ScrollViewer 之外,这会使 header 变粘但滚动条不会满。

你有很多方法可以增加粘性header,来自你的截图。它看起来只包含一组。请检查 Windows Community Toolkit ScrollHeader,并直接使用 StickyHeaderBehavior

例如

<ListView Name="listView">
    <interactivity:Interaction.Behaviors>
        <behaviors:StickyHeaderBehavior  />
    </interactivity:Interaction.Behaviors>
    <ListView.Header>
        <Grid MinHeight="100" Background="#FF0078D7">
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Sample Text"/>
        </Grid>
    </ListView.Header>
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <Grid MinHeight="25" Margin="10">
                <TextBlock Text="{Binding}" VerticalAlignment="Center" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.Items>
        <x:String>One</x:String>
        <x:String>Two</x:String>
        <x:String>Three</x:String>
        <x:String>Four</x:String>
        <x:String>Five</x:String>
        <x:String>Six</x:String>
        <x:String>Seven</x:String>
        <x:String>Eight</x:String>
        <x:String>Nine</x:String>
        <x:String>Ten</x:String>
        <x:String>Eleven</x:String>
        <x:String>Twelve</x:String>
        <x:String>Thirteen</x:String>
        <x:String>Fourteen</x:String>
        <x:String>Fifteen</x:String>
        <x:String>Sixteen</x:String>
        <x:String>Seventeen</x:String>
        <x:String>Eighteen</x:String>
        <x:String>Nineteen</x:String>
        <x:String>Twenty</x:String>
    </ListView.Items>
</ListView>

我为此找到了替代解决方案。基本上将 header 保留在列表视图 header 之外,并将其移动到具有 2 行的网格。 Header 内容和列表视图将在同一行中,并为列表视图保留一个填充以使列表视图保持在 Header 下方。使用 ListViewClipBehavior 解决滚动问题。

<Grid Margin="70,0,0,0">
        <Grid Margin="0,58,70,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="{x:Bind Strings.ui_language_setting}" Style="{ThemeResource H1TextBlockStyle}" TextTrimming="CharacterEllipsis" TextWrapping="WrapWholeWords"/>
            <TextBlock Grid.Row="1" Text="{x:Bind Strings.ui_language_copy}" Style="{ThemeResource BodyTitleTextBlockStyle}" Foreground="{StaticResource Gray9Brush}" TextWrapping="WrapWholeWords" HorizontalAlignment="Left" Margin="0,10,0,0" TextTrimming="CharacterEllipsis"/>
        </Grid>
        <ListView x:Name="LanguagesListView" Style="{StaticResource LanguagesListViewStyle}" ItemsSource="{x:Bind ViewModel.Languages}" SelectedItem="{x:Bind ViewModel.SelectedLanguage, Mode=TwoWay}" HorizontalAlignment="Stretch" Padding="0,160,0,0" Margin="0,0,0,0">
            <interactivity:Interaction.Behaviors>
                <behaviors:ListViewClipBehavior Padding="0,160,0,0" />
            <interactivity:Interaction.Behaviors>
        </ListView>
</grid>