WPF滚动条样式自定义,ScrollViewer样式自定义

在做wpf界面制作中布局经常用到ScrollViewer控件,默认的样式很丑,跟自己设计的界面风格不搭配,需要修改成跟自己界面设计风格一样的话需要修改它的默认样式。

下面就分享下代码:

<ScrollViewer HorizontalScrollBarVisibility="Visible" Template="{DynamicResource ScrollViewerControlTemplate1}"></ScrollViewer>

上面是ScrollViewer使用方法

<ControlTemplate x:Key="ScrollViewerControlTemplate1" 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="BlueViolet" 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 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}" Style="{DynamicResource ScrollBarStyle1}"/>
            <ScrollBar 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}" Style="{DynamicResource ScrollBarStyle1}"/>
        </Grid>
    </ControlTemplate>

修改ScrollViewer的ControlTemplate,这里面有两个ScrollBar是两个滚动条,一个是纵向,一个是横向的。主要是修改这两个ScrollBar的样式就可以了

<Style x:Key="ScrollBarStyle1" TargetType="{x:Type ScrollBar}">
        <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollBar}">
                    <Grid x:Name="Bg" Background="Transparent" SnapsToDevicePixels="true">
                        <!--<Grid.RowDefinitions>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                            <RowDefinition Height="0.00001*"/>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                        </Grid.RowDefinitions>-->
                        <Rectangle Grid.RowSpan="3" x:Name="_Rectangle" RadiusX="5" RadiusY="5" Fill="CadetBlue" />
                        
                        <Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}">
                            <Track.DecreaseRepeatButton>
                                <RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
                            </Track.DecreaseRepeatButton>
                            <Track.IncreaseRepeatButton>
                                <RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
                            </Track.IncreaseRepeatButton>
                            <Track.Thumb>
                                <Thumb Style="{StaticResource ScrollBarThumb}" Themes:ScrollChrome.ScrollGlyph="VerticalGripper"/>
                            </Track.Thumb>
                        </Track>
                        <!--<RepeatButton Command="{x:Static ScrollBar.LineUpCommand}" VerticalAlignment="Top" Height="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="UpArrow"/>
                        <RepeatButton Command="{x:Static ScrollBar.LineDownCommand}" VerticalAlignment="Bottom" Height="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="DownArrow"/>-->
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="_Rectangle" Value="{StaticResource ScrollBarDisabledBackground}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Orientation" Value="Horizontal">
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="MinWidth" Value="0"/>
                <Setter Property="Height" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="MinHeight" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="Background" Value="{StaticResource HorizontalScrollBarBackground}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ScrollBar}">
                            <Grid x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                                <!--<Grid.ColumnDefinitions>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                    <ColumnDefinition Width="0.00001*"/>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                </Grid.ColumnDefinitions>-->
                                <Rectangle Grid.RowSpan="3" x:Name="_Rectangle" RadiusX="5" RadiusY="5" Fill="CadetBlue" />
                                <!--<RepeatButton Command="{x:Static ScrollBar.LineLeftCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="LeftArrow"/>-->
                                <Track x:Name="PART_Track" Grid.Column="1" IsEnabled="{TemplateBinding IsMouseOver}">
                                    <Track.DecreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
                                    </Track.DecreaseRepeatButton>
                                    <Track.IncreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
                                    </Track.IncreaseRepeatButton>
                                    <Track.Thumb>
                                        <Thumb Style="{StaticResource ScrollBarThumb}" Themes:ScrollChrome.ScrollGlyph="HorizontalGripper"/>
                                    </Track.Thumb>
                                </Track>
                                <!--<RepeatButton Grid.Column="2" Command="{x:Static ScrollBar.LineRightCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="RightArrow"/>-->
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Fill" TargetName="_Rectangle" Value="{StaticResource ScrollBarDisabledBackground}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
上面就是ScrollBar的样式,上面说了这里面有两个ScrollBar的样式,默认ScrollViewer的横向滚动条是隐藏的,需要给ScrollViewer的属性HorizontalScrollBarVisibility="Visible"设置为显示就可以了。这个大家都知道。上面的样式中在Style.Triggers里就是横向滚动条的样式了。跟纵向的几乎一样。

上面的样式中我把系统自带的上下左右的三角箭头给注释了,感觉没什么大用处。

现在说说主要修改的吧,原来默认的背景写在Grid上面的,但是Grid无法实现圆角,所以写一个Rectangle来完成滚动条的低框圆角。

<Rectangle Grid.RowSpan="3" x:Name="_Rectangle" RadiusX="5" RadiusY="5" Fill="CadetBlue" />

就是这句。那么滑动的那个滚动条按钮的样式呢放在Track.Thum的Thum样式中。具体样式:

<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}">
                    <!--<Themes:ScrollChrome x:Name="Chrome" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsDragging}" SnapsToDevicePixels="true" Themes:ScrollChrome.ScrollGlyph="{TemplateBinding Themes:ScrollChrome.ScrollGlyph}"/>-->
                    <Border CornerRadius="5" Background="BlueViolet" Cursor="Hand" Margin="2"></Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

一样的,默认的样式要注释掉,为了实现圆角使用了Border的CornerRadius来实现圆角。这样就完成了ScrollViewer的样式修改。

下面把全部样式贴出来:

<ControlTemplate x:Key="ScrollViewerControlTemplate1" 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="BlueViolet" 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 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}" Style="{DynamicResource ScrollBarStyle1}"/>
            <ScrollBar 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}" Style="{DynamicResource ScrollBarStyle1}"/>
        </Grid>
    </ControlTemplate>

    <!-- 不可用颜色 -->
    <SolidColorBrush x:Key="ScrollBarDisabledBackground" Color="#F4F4F4"/>
    
    <!--#region 上下左右箭头按钮-->
    <Style x:Key="ScrollBarButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Border Background="YellowGreen" CornerRadius="2,2,0,0" Margin="2"/>
                    <!--<Themes:ScrollChrome x:Name="Chrome" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" SnapsToDevicePixels="true" Themes:ScrollChrome.ScrollGlyph="{TemplateBinding Themes:ScrollChrome.ScrollGlyph}"/>-->
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!--#endregion 上下左右箭头按钮-->
    
    <Style x:Key="VerticalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <!--#region 滚动条按钮-->
    <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}">
                    <!--<Themes:ScrollChrome x:Name="Chrome" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsDragging}" SnapsToDevicePixels="true" Themes:ScrollChrome.ScrollGlyph="{TemplateBinding Themes:ScrollChrome.ScrollGlyph}"/>-->
                    <Border CornerRadius="5" Background="BlueViolet" Cursor="Hand" Margin="2"></Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!--#endregion 滚动条按钮-->
    <LinearGradientBrush x:Key="HorizontalScrollBarBackground" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#E1E1E1" Offset="0"/>
        <GradientStop Color="#EDEDED" Offset="0.20"/>
        <GradientStop Color="#EDEDED" Offset="0.80"/>
        <GradientStop Color="#E3E3E3" Offset="1"/>
    </LinearGradientBrush>
    <Style x:Key="HorizontalScrollBarPageButton" TargetType="{x:Type RepeatButton}">
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Focusable" Value="false"/>
        <Setter Property="IsTabStop" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="ScrollBarStyle1" TargetType="{x:Type ScrollBar}">
        <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ScrollBar}">
                    <Grid x:Name="Bg" Background="Transparent" SnapsToDevicePixels="true">
                        <!--<Grid.RowDefinitions>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                            <RowDefinition Height="0.00001*"/>
                            <RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
                        </Grid.RowDefinitions>-->
                        <Rectangle Grid.RowSpan="3" x:Name="_Rectangle" RadiusX="5" RadiusY="5" Fill="CadetBlue" />
                        
                        <Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}">
                            <Track.DecreaseRepeatButton>
                                <RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
                            </Track.DecreaseRepeatButton>
                            <Track.IncreaseRepeatButton>
                                <RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Style="{StaticResource VerticalScrollBarPageButton}"/>
                            </Track.IncreaseRepeatButton>
                            <Track.Thumb>
                                <Thumb Style="{StaticResource ScrollBarThumb}" Themes:ScrollChrome.ScrollGlyph="VerticalGripper"/>
                            </Track.Thumb>
                        </Track>
                        <!--<RepeatButton Command="{x:Static ScrollBar.LineUpCommand}" VerticalAlignment="Top" Height="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="UpArrow"/>
                        <RepeatButton Command="{x:Static ScrollBar.LineDownCommand}" VerticalAlignment="Bottom" Height="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="DownArrow"/>-->
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Fill" TargetName="_Rectangle" Value="{StaticResource ScrollBarDisabledBackground}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Orientation" Value="Horizontal">
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="MinWidth" Value="0"/>
                <Setter Property="Height" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="MinHeight" Value="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarHeightKey}}"/>
                <Setter Property="Background" Value="{StaticResource HorizontalScrollBarBackground}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ScrollBar}">
                            <Grid x:Name="Bg" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                                <!--<Grid.ColumnDefinitions>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                    <ColumnDefinition Width="0.00001*"/>
                                    <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/>
                                </Grid.ColumnDefinitions>-->
                                <Rectangle Grid.RowSpan="3" x:Name="_Rectangle" RadiusX="5" RadiusY="5" Fill="CadetBlue" />
                                <!--<RepeatButton Command="{x:Static ScrollBar.LineLeftCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="LeftArrow"/>-->
                                <Track x:Name="PART_Track" Grid.Column="1" IsEnabled="{TemplateBinding IsMouseOver}">
                                    <Track.DecreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageLeftCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
                                    </Track.DecreaseRepeatButton>
                                    <Track.IncreaseRepeatButton>
                                        <RepeatButton Command="{x:Static ScrollBar.PageRightCommand}" Style="{StaticResource HorizontalScrollBarPageButton}"/>
                                    </Track.IncreaseRepeatButton>
                                    <Track.Thumb>
                                        <Thumb Style="{StaticResource ScrollBarThumb}" Themes:ScrollChrome.ScrollGlyph="HorizontalGripper"/>
                                    </Track.Thumb>
                                </Track>
                                <!--<RepeatButton Grid.Column="2" Command="{x:Static ScrollBar.LineRightCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}" Themes:ScrollChrome.ScrollGlyph="RightArrow"/>-->
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Fill" TargetName="_Rectangle" Value="{StaticResource ScrollBarDisabledBackground}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

写的有点儿垃圾,但是效果实现了。效果图如下:



版权声明:本文为zhouwenguang163原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。