开发者

Silverlight ScrollViewer - fade in\out the scrollbar

I have a scrollviewer and I want to animate the way the vertical scrollbar appears. The scrollbar is set to AUTO , so I want it to fade in when needed and fade out when not needed. I know how to drill into templates and change colors and appearance, but开发者_运维知识库 can I make a change like this ?


This was a fun question. Since Scrollbar and ScrollViewer are sealed this was a bit of a challenge. (I thought of making a copy of ScrollViewer using Reflector, but here is a XAML-only solution).

When I heard animation, I thought states. It would have been nice if ScrollViewer was implemented using states, but unfortunately, it was not. By using DataStateBehavior, we can create states out of a property -- in this case, states for the ComputedVerticalScrollBarVisibility property. For some reason, it didn't work to bind the DataStateBehavior to the ScrollViewer's ComputedVerticalScrollBarVisibility using TemplateBinding. (Anyone know why?) I was able to bind it to the VerticalScrollbar Visibility property, but I decided not to: In order for the Fade out to work, I didn't want the VerticalScrollbar.Visibility to still be bound to ComputedVerticalScrollBarVisibility because if it was, the scrollbar would immediately disapper when the property changed. Instead, I used the VerticalScrollbar Tag property to hold the ComputedVerticalScrollBarVisibility and bound the DataStateBehavior to the VerticalScrollbar Tag.

Now that states are in place, it was an easy matter to set the Opacity for each state and the state transition duration and, voila!, you have a fade in ScrollViewer.

<UserControl
    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:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SilverlightApplication5.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <Style x:Key="ScrollViewerStyle1" TargetType="ScrollViewer">
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
            <Setter Property="Padding" Value="4"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ScrollViewer">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="VisualStateGroup">
                                    <VisualStateGroup.Transitions>
                                        <VisualTransition GeneratedDuration="0:0:0.5"/>
                                    </VisualStateGroup.Transitions>
                                    <VisualState x:Name="VerticalVisible">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="VerticleHidden">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid Background="{TemplateBinding Background}">
                                <i:Interaction.Behaviors>
                                    <ei:DataStateBehavior Binding="{Binding Tag, ElementName=VerticalScrollBar}" Value="Visible" TrueState="VerticalVisible" FalseState="VerticleHidden"/>
                                </i:Interaction.Behaviors>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <ScrollContentPresenter x:Name="ScrollContentPresenter" Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}"/>
                                <Rectangle Grid.Column="1" Fill="#FFE9EEF4" Grid.Row="1"/>

                                <ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Margin="0,-1,-1,-1" Minimum="0" Orientation="Vertical" Grid.Row="0" Tag="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" Width="18"/>
                                <ScrollBar x:Name="HorizontalScrollBar" Grid.Column="0" Height="18" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Margin="-1,0,-1,-1" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="Beige">
        <ScrollViewer VerticalScrollBarVisibility="Auto"  Style="{StaticResource ScrollViewerStyle1}">
            <Rectangle Margin="10" Fill="LightBlue" MinHeight="300" />
        </ScrollViewer>
    </Grid>
</UserControl>

To see this in action, run this code and shrink the browser window. The scrollbar will fade into view.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜