9

我想把我的 ScrollViewer 放在这样一种方式,它重叠/坐在它滚动的内容之上。我会设置 ScrollViewer 的不透明度,以便内容在下面可见。

据我了解默认的 ScrollViewer,这似乎不可能开箱即用,因为内容嵌套在 ScrollViewer 内。

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

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

4

3 回答 3

16

我想我现在明白你所说的“在顶部”是什么意思 - 一种方法是使用控制模板,使 ScrollContentPresenter 跨越网格的两行和两列,而 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>

结果是这样的:

花哨的透明滚动

修改这一点很简单,使 ScrollBars 最初是非常透明的(例如,Opacity = 0.2),并在鼠标进入 ScrollBar 时使它们变得更加不透明。这将是一个很好的效果,并且会在需要它们之前将 ScrollBars 挡在外面。

编辑:

我已经在我的博客上写了这个,供那些想要更多细节的人使用。

于 2009-01-29T12:38:39.693 回答
1

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

话虽如此,如果 ScrollViewer 没有执行您想要的操作,我建议您创建 ScrollBar 控件并处理由它生成的事件,在事件处理程序中移动您希望滚动的内容。你甚至可以做一些花哨的数据绑定来避免编写事件处理程序。我不确定您将如何正确剪辑内容,但这是一种新的蠕虫。

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

于 2009-01-29T08:11:08.613 回答
1

我不确定您是否希望将 scrollviewer 的滚动条放在内容之上 - 如果是,请回答 1,如果您希望整个 scrollViewer 在内容之上,请参阅答案 2。

1) 您可以通过应用模板来更改 WPF 中任何内容的视觉表示。在这种情况下,诀窍是找到 ScrollViewer 的现有表示形式,然后基本上重新实现所有相同的视觉效果,只是根据需要更改 ScrollBar 的位置。有几种方法可以找到控件的所有视觉效果 - 最简单的是来自WPF MSDN 示例- 并且微软提供的 ScrollViewer 示例很好地展示了如何更改滚动条的位置。

顺便说一句,微软倾向于在他们的示例中加载很多你并不真正需要的额外 Xaml - 使用模板(无情地删减代码)直到它只做你想要的,而不是更多。

2) 我将滚动视图放置在内容之上的方法是使用两个相互叠加的滚动查看器。“顶部”很小,半透明(不透明度 = 50)并处理滚动,底部较大并且有文档。从顶部的 ScrollViewer 连接滚动事件,这样它也将滚动底部的事件。

于 2009-01-29T09:25:28.817 回答