WPF:如何防止滚动条覆盖列表类型视图中的标题 [英] WPF: How to prevent scrollbar from overlaying headers in list type views

查看:120
本文介绍了WPF:如何防止滚动条覆盖列表类型视图中的标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了ScrollViewer样式,旨在显示覆盖可滚动内容的滚动条.我根据其他stackoverflow帖子

I have made a ScrollViewer style which is designed to show scrollbars overlaying the scrollable content. I produced it based on other stackoverflow posts such as this.

许多其他方案和MY方案之间的区别在于,我将scrollviewer样式应用于包含标题的ListView.通常,用户希望滚动查看器不会覆盖标题,如下图所示. (我用橙色突出显示了条形,使其更加明显)

The difference between a lot of other scenarios and MY scenario, is that I am applying my scrollviewer style to a ListView which includes a header. Generally, users would expect a scrollviewer to not overlay the headers as in my image below. (I've highlighted the bar in orange to make it more obvious)

(栏应在标题开始之前停止.必须指出的是,可滚动内容的第一个元素未隐藏在标题下方.在图像中,栏向下滚动了约15%.)

(The bar should stop before the header starts. It's important to mention that the first element(s) of the scrollable content are NOT hidden underneath the header. In the image I have scrolled the bar down ~15%.)

我尝试将scrollviewer中的滚动条锚定在底部,并将其高度设置为"ViewportHeight",还尝试将各种元素放置在网格的第二行(第1行)(请参见下面的代码)无济于事.

I have tried anchoring the scrollbars in my scrollviewer to the bottom and setting their height to "ViewportHeight" and also tried placing various elements in the second row (row #1) of the grid (see code below) to no avail.

如何使滚动查看器在标题的底部之前停止?

How can I get the scrollviewer to stop before the base of the headers?

<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="1">
                            <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"
                                   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>

推荐答案

这比我想象的要容易得多,部分原因是事实(与我的看法相反),WPF对于源WPF排序并不珍贵.呈现滚动内容和滚动条的元素的位置/位置(底座面板和上面的两个滚动条中的所有元素).

This was a lot easier to fix than I imagined, thanks in part to the fact that (contrary to my belief) WPF is not precious about the source WPF ordering/positioning of the elements which render the scroll content and the scroll bars (everything within the dockpanel and the two scrollbars above).

这样,就像在视图中添加额外的(第3行)一样简单,我可以在其中放置标题.然后,我只是简单地将内容和垂直滚动条的分配行更改为以前的+1.

As such, it was as simple as adding an additional (3rd) row to the view, into which I can place my headers. Then I simply changed the assigned row of the content and vertical scroll bar to +1 what it was before.

结果是一个滚动条,它与滚动内容包含在同一行中,因此不会泄漏到标题上.

The result is a scrollbar which is contained within the same row as the scroll content, which therefore doesn't leak over onto the headers.

<ControlTemplate TargetType="{x:Type ScrollViewer}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <GridViewHeaderRowPresenter x:Name="GridViewHeaderRowPresenter" Margin="2,0,2,0" Grid.Row="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}"/>
                        <DockPanel Margin="{TemplateBinding Padding}" Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="1">
                            <ScrollViewer DockPanel.Dock="Top" Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="2" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Focusable="False">
                            </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="1"
                                   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>

以上是我更改过的唯一代码部分.

The above is the only section of code which I altered.

此外,这篇文章很有帮助.

这篇关于WPF:如何防止滚动条覆盖列表类型视图中的标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆