WPF(滚动条)
ScrollBar控件出奇复杂。它实际上是一个由更小部分组成的集合。
滚动条的背景由Track类表示(实际上是一个具有阴影并且被拉伸占满整个滚动条长度的矩形)。滚动条的末尾处是按钮,通过这些按钮可以向上或向下(或向左或向右)滚动一个步长。这些按钮是RepeatButton类的实例,该类继承自ButtonBase类。RepeatButton类和普通Button类之间的重要区别在于,如果在RepeatButton按钮上保持鼠标按下的状态,就会反复触发Click事件。
在滚动条的中间是代表滚动内容中当前位置的Thumb元素。并且最有趣的是,滑块两侧的空白实际上由另外两个RepeatButton对象构成,它们是透明的。当单击这两个按钮中的一个时,滚动条会滚动一整页(一页是滚动内容所在的可见窗口中的内容容量)。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ScrollBarThumbStyle" TargetType="Thumb">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Margin" Value="1 0 1 0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Border Background="DarkCyan" CornerRadius="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarPageBtnStyle" TargetType="RepeatButton">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" BorderBrush="#00B2EE" BorderThickness="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarLineBtnStyle" TargetType="RepeatButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Margin="1">
<Border x:Name="Border" BorderThickness="1" Background="#F0FFF0" BorderBrush="#838B8B" CornerRadius="10 10 0 0"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Gold"/>
</Trigger>
<Trigger Property="Tag" Value="U">
<Setter TargetName="Border" Property="CornerRadius" Value="5 5 0 0"/>
</Trigger>
<Trigger Property="Tag" Value="D">
<Setter TargetName="Border" Property="CornerRadius" Value="0 0 5 5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="VerticalScrollBar" TargetType="ScrollBar">
<Border BorderBrush="Beige" BorderThickness="2" CornerRadius="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="18"/>
<RowDefinition Height="*"/>
<RowDefinition MaxHeight="18"/>
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0" Height="18" Command="ScrollBar.LineUpCommand" Tag="U" Style="{StaticResource ScrollBarLineBtnStyle}">
<Path Fill="#008B8B" Data="M 0 4 L 8 4 L 4 0 Z"/>
</RepeatButton>
<Track x:Name="PART_Track" Grid.Row="1" IsDirectionReversed="True" ViewportSize="10">
<Track.DecreaseRepeatButton>
<RepeatButton Command="ScrollBar.PageUpCommand" Style="{StaticResource ScrollBarPageBtnStyle}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="ScrollBar.PageDownCommand" Style="{StaticResource ScrollBarPageBtnStyle}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumbStyle}"/>
</Track.Thumb>
</Track>
<RepeatButton Grid.Row="3" Height="18" Command="ScrollBar.LineDownCommand" Tag="D" Style="{StaticResource ScrollBarLineBtnStyle}">
<Path Fill="#008B8B" Data="M 0 0 L 4 4 L 8 0 Z"/>
</RepeatButton>
</Grid>
</Border>
</ControlTemplate>
<Style x:Key="ScrollBarStyle" TargetType="ScrollBar">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Width" Value="18"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
- 垂直滚动条由一个包含三行的网格构成。顶行和底行容纳两端的按钮(并显示为箭头)。它们固定占用18各单位。中间部分容纳Track元素,占用了剩余空间。
- Track元素名为PART_Track。为使ScrollBar类能够成功地关联到它的代码,必须使用这个名称。
- Track.ViewportSize属性被设置为0时可确保Thumb元素总有相同的尺寸(通常,滑块根据内容按比例地改变尺寸,因此如果滚动的内容在窗口中基本上能够显示,这时滑块会变得较长)。
<Window x:Class="WpfApp2.WindowTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="WindowTemplate" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DictionaryScroll.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ListBox Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ControlTemplate.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}"/>
</Style>
</ControlTemplate.Resources>
<Border x:Name="Border" Background="#8EE5EE" BorderBrush="Yellow" BorderThickness="2" CornerRadius="20">
<ScrollViewer Focusable="False" Margin="10">
<ItemsPresenter Margin="10"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="0 1 0 1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="White" BorderThickness="2">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="20" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" BeginTime="0:0:0.1" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Border.BorderBrush" Value="Green"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Border.Background" Value="Gold"/>
<Setter TargetName="Border" Property="TextBlock.Foreground" Value="Chocolate"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
<ListBoxItem Content="666" />
<ListBoxItem Content="777" />
<ListBoxItem Content="888" />
</ListBox>
</Grid>
</Window>