WPF滚动条覆盖内容

5
我正在为 scrollviewer 自定义样式,目前运作良好。但是我希望 scrollbar 可以在内容上方,这样我的控件宽度就不会因为 scrollbar 而破损。
如下图所示,顶部的控件因为 scrollbar 改变而破坏了布局。请问各位是否知道如何使我的 scrollbar 的背景透明,这样我的控件就能被 scrollbar 遮盖住了呢?
2个回答

7

资源

 <Window.Resources>
    <Style x:Key="ListboxStyle" TargetType="ListBox">
        <Style.Resources>             

            <Style x:Key="ScrollBarThumbVertical" TargetType="{x:Type Thumb}">
                <Setter Property="OverridesDefaultStyle" Value="true"/>
                <Setter Property="IsTabStop" Value="false"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Thumb}">
                            <Rectangle x:Name="rectangle" Fill="#CDCDCD" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Fill" TargetName="rectangle" Value="#A6A6A6"/>
                                </Trigger>
                                <Trigger Property="IsDragging" Value="true">
                                    <Setter Property="Fill" TargetName="rectangle" Value="#606060"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style TargetType="RepeatButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="RepeatButton">
                            <Grid>
                                <ContentPresenter></ContentPresenter>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style TargetType="{x:Type ScrollBar}">
                <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
                <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>                                       
                <Setter Property="BorderThickness" Value="1,0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ScrollBar}">
                            <Grid x:Name="Bg" Width="8" Margin="0,15,0,15" Background="Transparent" SnapsToDevicePixels="true">
                                <Grid.RowDefinitions>
                                    <RowDefinition  MaxHeight="0"/>
                                    <RowDefinition Height="0.00001*"/>
                                    <RowDefinition Height="0"/>
                                </Grid.RowDefinitions>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Background="Transparent" Grid.Row="1"/>
                                <RepeatButton Height="0" Width="0" x:Name="PART_LineUpButton" Command="{x:Static ScrollBar.LineUpCommand}" IsEnabled="{TemplateBinding IsMouseOver}"/>                                                                           
                                <Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
                                    <Track.DecreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" />
                                    </Track.DecreaseRepeatButton>
                                    <Track.IncreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" />
                                    </Track.IncreaseRepeatButton>
                                    <Track.Thumb>
                                        <Thumb Style="{StaticResource ScrollBarThumbVertical}"/>
                                    </Track.Thumb>
                                </Track>
                                <RepeatButton x:Name="PART_LineDownButton" Height="0" Width="0" Command="{x:Static ScrollBar.LineDownCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2"/>                                  
                            </Grid>                    
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>                   
            </Style>

            <Style TargetType="{x:Type ScrollViewer}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate  TargetType="{x:Type ScrollViewer}">
                            <Grid x:Name="Grid"  HorizontalAlignment="Right">                                  
                                <ScrollContentPresenter   x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" />
                                <ScrollBar x:Name="PART_VerticalScrollBar" HorizontalAlignment="Right" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow"  Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Style.Resources>
    </Style>
</Window.Resources>

Xaml

<ListBox Style="{StaticResource ListboxStyle}" Height="400" Width="150" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
    <TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
</ListBox>

结果

在此输入图像描述


(注:本文未进行解释,保留了HTML标签)

哇,不错!非常感谢。那么滚动条本身和增加/减少按钮之间的空间呢? - Reverb
1
我不得不对你的ScrollView样式进行了一些更改。<Grid x:Name="Grid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> ... 对于PART_ScrollContentPresenter,我已将其列设置为“0”。 - gmetax
1
这是一个非常优秀的解决方案!请注意,主要的魔法是在ScrollViewer模板覆盖中完成的。我喜欢这种方式,因为你不需要添加更多的代码/标记,只需从原始模板中删除一些元素即可。稍加调整,就可以轻松地按照自己的需求进行定制! - Pedro Henrique
太好了,但我无法显示水平滚动条,我该怎么做? - CodingNinja
@CodingNinja:你需要添加和编辑ScrollBar x:Name="PART_horizontalScrollBar"的样式。为此,需要更新整个scrollviewer模板。谢谢。 - Heena
1
@HeenaPatil 我尝试了一次失败了,然后再试了一次,最终成功了,我已经忘记自己做了哪些微小的代码更改了...( ̄▽ ̄)╭ - CodingNinja

3

ScrollBar被父级ScrollViewer放置在Grid中,因此您需要为其提供一个新的ControlTemplate。您可以使用Grid.RowSpanGrid.ColumnSpan来使ScrollViewer内容拉伸以填充可用空间。尝试类似于以下内容:

<Style TargetType="{x:Type ScrollViewer}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <ScrollContentPresenter Grid.ColumnSpan="2" Grid.RowSpan="2" />
                    <ScrollBar Grid.Column="1" x:Name="PART_VerticalScrollBar" 
                        Value="{TemplateBinding VerticalOffset}" Maximum="{
                        TemplateBinding ScrollableHeight}" ViewportSize="{
                        TemplateBinding ViewportHeight}" Background="Transparent" />
                    <ScrollBar Grid.Row="1" x:Name="PART_HorizontalScrollBar" 
                        Orientation="Horizontal" Value="{TemplateBinding 
                        HorizontalOffset}" Maximum="{TemplateBinding ScrollableWidth}"
                        ViewportSize="{TemplateBinding ViewportWidth}" 
                        Background="Transparent" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

可能需要将ScrollContentPresenter更改为<ScrollContentPresenter CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" HorizontalAlignment="Left" Grid.ColumnSpan="2" Grid.RowSpan="2" Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}"/>,否则如果您全局使用此样式而没有键,则会干扰使用嵌入式ScrollViewer(如TextBox)的任何控件,导致在输入时文本无法滚动。 - AlishahNovin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接