如何将ScrollViewer放在它应该滚动的内容之上

时间:2009-01-29 07:35:42

标签: wpf scrollbar controltemplate styling scrollviewer

我想让我的ScrollViewer以它重叠/位于其滚动的内容之上的方式放置。我会设置ScrollViewer的不透明度,以便在下面显示内容。

据我了解默认的ScrollViewer,由于内容嵌套在ScrollViewer中,因此似乎无法开箱即用。

关于如何使这项工作的任何想法?

编辑:据我所知,ScrollViewer是一个装饰器,内容不知道ScrollViewer。这种分离很好,我不希望内容知道ScrollViewer。我尝试做的是纯粹的视觉(布局)事物。只需在内容之上显示ScrollViewer.ScrollViewer的行为应保持不变。

3 个答案:

答案 0 :(得分:15)

我想我现在理解你在“顶部”的意思 - 一种方法是使用一个控制模板,使ScrollContentPresenter跨越网格的两行和一列,而ScrollBars位于第二行和第二列。 ScrollBars设置为半透明。现在,内容将在滚动条下绘制!

我试过的样式如下:

<Style x:Key="SVStyle" TargetType="{x:Type ScrollViewer}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <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>

使用示例:

<ScrollViewer HorizontalScrollBarVisibility="Auto" Style="{StaticResource SVStyle}" >
    <StackPanel>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >World World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
        <Button Height="100" Width="800" >Hello World</Button>
    </StackPanel>
</ScrollViewer>

结果如下:

fancy transparent scrolling

简单地修改它以使ScrollBars最初非常透明(例如,Opacity = 0.2)并且当鼠标进入ScrollBar时它们变得更不透明。这将是一个很好的效果,并会在需要之前让ScrollBars保持原状。

编辑:

我已经在my blog上为那些想要了解更多细节的人写了这篇文章。

答案 1 :(得分:1)

这个想法是ScrollViewer是它滚动和剪辑的东西的装饰器。滚动的东西完全不知道滚动。这简单而优雅 - 为什么在你的情况下还不够?

话虽如此,如果ScrollViewer没有做你想做的事情,我建议你创建ScrollBar控件并处理它生成的事件,移动你想在事件处理程序中滚动的内容。您甚至可以进行一些奇特的数据绑定,以避免编写事件处理程序。我不确定你是如何正确剪辑内容的,但这是一种新的蠕虫病毒。

如果需要将一个控件布局在另一个控件之上,请使用画布控件。

答案 2 :(得分:1)

我不确定您是否希望将滚动查看器的滚动条放在内容的顶部 - 如果是,请回答1,如果您希望内容的整个scrollViewer在内容上看到答案2.

1)您可以通过应用模板更改WPF中任何内容的可视化表示。在这种情况下的技巧是找到ScrollViewer的现有表示,然后基本上重新实现所有相同的视觉效果,只需根据需要更改ScrollBar的位置。有几种方法可以找到控件的所有视觉效果 - 最简单的方法来自WPF MSDN Samples - 很好地,Microsoft的ScrollViewer example provided显示了如何更改滚动条的位置。

BTW微软倾向于使用你真正不需要的大量额外Xaml加载他们的示例 - 用模板播放(无情地删除代码),直到它完成你想要的而不是更多。

2)我将滚动视图置于内容顶部的方法是使用两个放在彼此顶部的滚动查看器。 'top'是小的,半透明的(不透明度= 50)并且处理滚动,底部更大并且具有文档。从顶部的ScrollViewer连接滚动事件,以便它也可以滚动底部的滚动事件。