lilillliliil
lilillliliil

Reputation: 143

In WPF, how to customize the style of ScrollBar in ScrollViewer

I can add a ScrollBar style as global. But that will alse change all the ScrollBar except in ScrollViewer. How can I just change the style of ScrollBar in ScrollViewer. Maybe add a style with a Key and specify it to somewhere like a ControlTemplate.

Here is my fully ScrollBar style:

<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="IsTabStop" Value="false"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Thumb}">
                <Border x:Name="rectangle"
                            SnapsToDevicePixels="True"
                            Background="{StaticResource WordBlueBrush}"
                            Opacity="0.3"
                            CornerRadius="4"
                            Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}"/>   
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="rectangle" Property="Opacity" Value="1" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type ScrollBar}">
    <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>

    <Setter Property="Width" Value="14"/>
    <Setter Property="Margin" Value="-14 0 0 0" />
    <Setter Property="MinWidth" Value="{Binding Height, RelativeSource={RelativeSource Self}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ScrollBar}">
                <Grid x:Name="Bg" SnapsToDevicePixels="true">

                    <Border Padding="0 4">
                        <Track x:Name="PART_Track"
                        IsDirectionReversed="true"
                        IsEnabled="{TemplateBinding IsMouseOver}"
                        Width="8"
                        HorizontalAlignment="Center"
                           >
                            <Track.DecreaseRepeatButton>
                                <RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageUpCommand}" />
                            </Track.DecreaseRepeatButton>
                            <Track.IncreaseRepeatButton>
                                <RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageDownCommand}" />
                            </Track.IncreaseRepeatButton>
                            <Track.Thumb>
                                <Thumb Style="{StaticResource ScrollBarThumb  }" />
                            </Track.Thumb>
                        </Track>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 5

Views: 17127

Answers (1)

lilillliliil
lilillliliil

Reputation: 143

Finally, I got my solution.

1st, add a key to the ScrollBar style:

<Style x:Key="ViewerScrollBar" TargetType="{x:Type ScrollBar}">

2nd, right click the ScrollViewer in Visual Studio XAML Designer. Chose 'Edit Template'->'Edit a Copy':

Add ControlTemplate for ScrollViewer

3rd, in the 'Create Style Resource' dialog, specify a key for the ScrollViewer style and click 'OK':

Create Style Resource Dialog

4th, Visual Studio will automatically create the ControlTemplate for my ScrollViewer. Now, add Style="{StaticResource ViewerScrollBar}" for the horizontal ScrollBar and verticalScrollBar:

    <ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}">
        <Grid x:Name="Grid" Background="{TemplateBinding Background}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
            <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
            <ScrollBar Style="{StaticResource ViewerScrollBar}" x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
            <ScrollBar Style="{StaticResource ViewerScrollBar}" x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
        </Grid>
    </ControlTemplate>

Upvotes: 9

Related Questions