WPF 自定义滚动条(ScrollView、ScrollBar)样式
一、滚动条基本样式
本次修改Scrollview及ScrollBar滚动条样式是通过纯样式实现的。修改的内容包含滚动条的颜色,上下按钮的隐藏。另外添加了鼠标经过滚动条动画。
style样式如下:
<!-- ScrollViewer 滚动条 --> <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}"> <Grid> <!--滚动条颜色--> <Border Background="#646465" CornerRadius="3"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <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="Opacity" Value="0.2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <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="Opacity" Value="0.2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--滚动条上下按钮--> <Style x:Key="VerticalScrollBarPageButton2" 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="Opacity" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="#90000000" Width="0" Height="0"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="for_scrollbar" TargetType="{x:Type ScrollBar}"> <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/> <Setter Property="Stylus.IsFlicksEnabled" Value="false"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="Margin" Value="0,1,1,6"/> <Setter Property="Width" Value="10"/> <Setter Property="MinWidth" Value="5"/> <Setter Property="Opacity" Value="0.2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid x:Name="Bg" SnapsToDevicePixels="true"> <Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="auto"></RowDefinition> </Grid.RowDefinitions> <RepeatButton Grid.Row="0" Style="{StaticResource VerticalScrollBarPageButton2}" Command="{x:Static ScrollBar.PageUpCommand}"/> <Track x:Name="PART_Track" Grid.Row="1" IsEnabled="{TemplateBinding IsMouseOver}" IsDirectionReversed="true"> <Track.DecreaseRepeatButton> <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}" Command="{x:Static ScrollBar.PageUpCommand}"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource VerticalScrollBarPageButton}" Command="{x:Static ScrollBar.PageDownCommand}"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb Style="{StaticResource ScrollBarThumb}"/> </Track.Thumb> </Track> <RepeatButton Grid.Row="2" Style="{StaticResource VerticalScrollBarPageButton2}" Command="{x:Static ScrollBar.PageDownCommand}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="Orientation" Value="Horizontal"> <Setter Property="Background" Value="Transparent"/> <Setter Property="Margin" Value="1,0,6,1"/> <Setter Property="Height" Value="5"/> <Setter Property="MinHeight" Value="5"/> <Setter Property="Width" Value="Auto"/> <Setter Property="Opacity" Value="0.2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid x:Name="Bg" SnapsToDevicePixels="true"> <Track x:Name="PART_Track" IsEnabled="{TemplateBinding IsMouseOver}"> <Track.DecreaseRepeatButton> <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageLeftCommand}"/> </Track.DecreaseRepeatButton> <Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageRightCommand}"/> </Track.IncreaseRepeatButton> <Track.Thumb> <Thumb Style="{StaticResource ScrollBarThumb}"/> </Track.Thumb> </Track> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> <Style x:Key="for_scrollviewer" TargetType="{x:Type ScrollViewer}"> <Setter Property="BorderBrush" Value="LightGray"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollViewer}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True"> <Grid Background="{TemplateBinding Background}"> <ScrollContentPresenter Cursor="{TemplateBinding Cursor}" Margin="{TemplateBinding Padding}" ContentTemplate="{TemplateBinding ContentTemplate}"/> <ScrollBar x:Name="PART_VerticalScrollBar" HorizontalAlignment="Right" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Style="{StaticResource for_scrollbar}" ViewportSize="{TemplateBinding ViewportHeight}" Value="{TemplateBinding VerticalOffset}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/> <ScrollBar x:Name="PART_HorizontalScrollBar" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Style="{StaticResource for_scrollbar}" VerticalAlignment="Bottom" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/> </Grid> </Border> <ControlTemplate.Triggers> <EventTrigger RoutedEvent="ScrollChanged" > <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="PART_VerticalScrollBar" Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="PART_VerticalScrollBar" Storyboard.TargetProperty="Opacity" To="0.2" Duration="0:0:1" BeginTime="0:0:1"/> <DoubleAnimation Storyboard.TargetName="PART_HorizontalScrollBar" Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="PART_HorizontalScrollBar" Storyboard.TargetProperty="Opacity" To="0.2" Duration="0:0:1" BeginTime="0:0:1"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="MouseEnter" SourceName="PART_VerticalScrollBar"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="PART_VerticalScrollBar" Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:0.7"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="MouseLeave" SourceName="PART_VerticalScrollBar"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="PART_VerticalScrollBar" Storyboard.TargetProperty="Opacity" To="0.2" Duration="0:0:0.7"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="MouseEnter" SourceName="PART_HorizontalScrollBar"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="PART_HorizontalScrollBar" Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:0.7"/> </Storyboard> </BeginStoryboard> </EventTrigger> <EventTrigger RoutedEvent="MouseLeave" SourceName="PART_HorizontalScrollBar"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="PART_HorizontalScrollBar" Storyboard.TargetProperty="Opacity" To="0.2" Duration="0:0:0.7"/> </Storyboard> </BeginStoryboard> </EventTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--默认ScrollBar--> <Style TargetType="ScrollBar" BasedOn="{StaticResource for_scrollbar}"/> <!--默认ScrollView--> <Style TargetType="ScrollViewer" BasedOn="{StaticResource for_scrollviewer}"/>
修改之后的滚动条是影响全局的。
样式应用之后的效果如下:
引用示例:
<ScrollViewer Margin="10" Height="200" Width="100" BorderBrush="Gray" BorderThickness="1"> <StackPanel Orientation="Vertical"> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> <TextBlock Text="测试一"/> </StackPanel> </ScrollViewer>
所有代码已经上传到github:https://github.com/cmfGit/WpfDemo.git