Silverlight ScrollViewer - 淡入/淡出滚动条

发布于 2024-10-23 18:27:18 字数 101 浏览 6 评论 0原文

我有一个滚动查看器,我想为垂直滚动条的显示方式设置动画。滚动条设置为 AUTO ,所以我希望它在需要时淡入,在不需要时淡出。 我知道如何深入模板并更改颜色和外观,但我可以进行这样的更改吗?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终难愈 2024-10-30 18:27:18

这是一个有趣的问题。由于 Scrollbar 和 ScrollViewer 是密封的,这有点挑战。 (我想使用 Reflector 制作 ScrollViewer 的副本,但这里是仅 XAML 的解决方案)。

当我听到动画时,我想到了状态。如果 ScrollViewer 是使用状态来实现的,那就太好了,但不幸的是,事实并非如此。通过使用 DataStateBehavior,我们可以从属性创建状态 - 在本例中,是 ComputedVerticalScrollBarVisibility 属性的状态。由于某种原因,使用 TemplateBinding 将 DataStateBehavior 绑定到 ScrollViewer 的 ComputedVerticalScrollBarVisibility 不起作用。 (有人知道为什么吗?)我能够将其绑定到 VerticalScrollbar Visibility 属性,但我决定不这样做:
为了使淡出效果正常,我不希望 VerticalScrollbar.Visibility 仍绑定到 ComputedVerticalScrollBarVisibility,因为如果是这样,当属性更改时,滚动条将立即消失。相反,我使用 VerticalScrollbar Tag 属性来保存 ComputedVerticalScrollBarVisibility 并将 DataStateBehavior 绑定到 VerticalScrollbar Tag。

现在状态已就位,设置每个状态的不透明度和状态转换持续时间就很容易了,瞧!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>

要查看实际效果,请运行此代码并缩小浏览器窗口。滚动条将淡入视图。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文