9

ScrollViewer を、スクロールするコンテンツの上にオーバーラップ/配置するように配置したいと思います。コンテンツが下に表示されるように、ScrollViewer の Opacity を設定します。

私がデフォルトの ScrollViewer を理解している限り、コンテンツは ScrollViewer 内にネストされているため、そのままでは使用できないようです。

これを機能させる方法についてのアイデアはありますか?

編集: ScrollViewer はデコレータであり、コンテンツは ScrollViewer を認識していないことを理解しています。この分離は適切であり、コンテンツに ScrollViewer を認識させたくありません。私がやろうとしているのは、純粋に視覚的な (レイアウト) ことです。ScrollViewer をコンテンツの上に表示するだけです。ScrollViewer の動作は変更されません。

4

3 に答える 3

16

「一番上」の意味を理解できたと思います-それを行う1つの方法は、ScrollContentPresenterがグリッドの2つの行と列にまたがるコントロールテンプレートを使用し、ScrollBarsが2番目の行と列にあることです。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 が最初は非常に透明 (たとえば、不透明度 = 0.2) であり、マウスが ScrollBar に入るとより不透明になるように、これを変更するだけです。これは素晴らしい効果であり、ScrollBars が必要になるまで邪魔にならないようにします。

編集:

もう少し詳しく知りたい方のためにブログにまとめました。

于 2009-01-29T12:38:39.693 に答える
1

scrollviewerのスクロールバーをコンテンツの上に配置するかどうかはわかりません。その場合は1と答え、scrollViewer全体をコンテンツの上に配置する場合は回答2を参照してください。

1)テンプレートを適用することで、WPF内のあらゆるものの視覚的表現を変更できます。この場合の秘訣は、ScrollViewerの既存の表現が何であるかを見つけ、必要に応じてScrollBarの位置を変更するだけで、基本的にすべて同じビジュアルを再実装することです。コントロールのすべてのビジュアルを見つける方法はいくつかあります(最も簡単なのはWPF MSDNサンプルからです)。Microsoftが提供するScrollViewerのは、スクロールバーの位置を変更する方法を示しています。

ところで、Microsoftは、実際には必要のない多くの追加のXamlを使用してサンプルをロードする傾向があります。つまり、テンプレートを使用して、必要な処理が実行され、それ以上実行されなくなるまで、テンプレートを試してみてください。

2)スクロールビューをコンテンツの上に配置する私のアプローチは、2つのスクロールビューアーを互いに重ねて使用することです。「上部」は小さく、半透明(不透明度= 50)でスクロールを処理し、下部は大きく、ドキュメントがあります。スクロールイベントを上部のScrollViewerからワイヤリングして、下部のScrollViewerもスクロールするようにします。

于 2009-01-29T09:25:28.817 に答える
1

アイデアは、ScrollViewer がスクロールしてクリップするもののデコレータであるということです。スクロールされているものは、スクロールをまったく認識していません。これはシンプルでエレガントです。なぜあなたのケースでは十分ではないのでしょうか?

そうは言っても、ScrollViewer が意図したとおりに動作しない場合は、ScrollBar コントロールを作成し、それによって生成されたイベントを処理して、スクロールするコンテンツをイベント ハンドラーで移動することをお勧めします。イベント ハンドラーの記述を避けるために、手の込んだデータ バインディングを実行できる場合もあります。コンテンツを正しくクリップする方法はわかりませんが、これはワームの新しい缶詰です。

あるコントロールを別のコントロールの上にレイアウトする必要がある場合は、キャンバス コントロールを使用します。

于 2009-01-29T08:11:08.613 に答える