如何禁用WPF ScrollViewer来刷新视图

时间:2013-12-09 08:31:53

标签: wpf user-interface scroll scrollview freeze

我正在使用堆栈面板来显示幻灯片。堆栈面板包含两个图像。 每个图像都绑定到视图模型,其中包含磁盘上图像的路径。在一般情况下,列表中有超过2个图像。 有一个无限循环用于改变当前和下一个指向图像的指针,这样在滑动转换完成后,当前图像变为前一个,下一个变为当前图像。 通过将滚动查看器从0到100%的可滚动扩展区域更改来进行幻灯片切换。

这很有效,甚至非常快。这是使用MVVM模式为无穷无尽的图像列表实现幻灯片转换的最简单方法。 我的问题是,幻灯片转换不时滑动并且没有在视觉上完全100%完成,但故事板动画完成事件被触发。 在ViewModel中,我正在移动Current和Next poitners,图像闪烁。有时可以看到一些闪烁。

当我将scoller从100%重新定位到0%时,我需要找到一种方法来暂时禁用ScrollViewer以显示任何视觉变化。

我需要暂时使WPF ScrollViewer无效,直到我将滚动位置从100%更改为0%,但这在屏幕上不可见。

我的意思是必须更改值,但必须冻结屏幕。

有可能吗?

XAML

    <UserControl.Resources>
    <Storyboard  x:Key="sbVerticalSlideEasingTransition"
                 AutoReverse="True" RepeatBehavior="Forever">

    <Storyboard  x:Key="sbVerticalSlideTransition"
                FillBehavior="HoldEnd">
        <!--SCROLL TO THE MULTIPLIER OF THE HEIGHT (BASICALLY AS THE PERCENTAGE)-->
        <DoubleAnimationUsingKeyFrames 
                            Storyboard.TargetName="Mediator"
                            Storyboard.TargetProperty="ScrollableHeightMultiplier">
                            <LinearDoubleKeyFrame KeyTime="00:0:0" Value="0" />
                            <LinearDoubleKeyFrame KeyTime="00:0:5" Value="1" />
                        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

</UserControl.Resources>

<Grid x:Name="gdContainer" Background="Black">
    <ScrollViewer x:Name="Scroller"  Visibility="{Binding Path=IsSlider, Mode=TwoWay, NotifyOnSourceUpdated=True, ElementName=slidePlayer,
                                                    Converter='{StaticResource BoolToVisibility}'}"
                  VerticalScrollBarVisibility="Hidden" 
                  HorizontalScrollBarVisibility="Disabled">
        <StackPanel x:Name="ScrollPanel">
            <ctrl:MediaElementEx x:Name="slide1"  Height="{Binding Path=ActualHeight, ElementName=gdContainer}" Width="{Binding Path=ActualWidth, ElementName=gdContainer}" />
            <ctrl:MediaElementEx x:Name="slide2"  Height="{Binding Path=ActualHeight, ElementName=gdContainer}" Width="{Binding Path=ActualWidth, ElementName=gdContainer}" />
        </StackPanel>
    </ScrollViewer>

    <!-- Mediator that forwards the property changes -->
    <cmn:ScrollViewerOffsetMediator x:Name="Mediator" ScrollViewer="{Binding ElementName=Scroller}"/>

</Grid>

ScrollViewer Mediator

这用于绑定不可直接绑定的scrollviewer的ScrollOffset

    /// <summary>
/// Mediator that forwards Offset property changes on to a ScrollViewer
/// instance to enable the animation of Horizontal/VerticalOffset.
/// </summary>
public class ScrollViewerOffsetMediator : FrameworkElement
{
    /// <summary>
    /// ScrollViewer instance to forward Offset changes on to.
    /// </summary>
    public ScrollViewer ScrollViewer
    {
        get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
        set { SetValue(ScrollViewerProperty, value); }
    }
    public static readonly DependencyProperty ScrollViewerProperty =
        DependencyProperty.Register(
            "ScrollViewer",
            typeof(ScrollViewer),
            typeof(ScrollViewerOffsetMediator),
            new PropertyMetadata(OnScrollViewerChanged));
    private static void OnScrollViewerChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var mediator = (ScrollViewerOffsetMediator)o;
        var scrollViewer = (ScrollViewer)(e.NewValue);
        if (null != scrollViewer)
        {
            scrollViewer.ScrollToVerticalOffset(mediator.VerticalOffset);
        }
    }

    /// <summary>
    /// VerticalOffset property to forward to the ScrollViewer.
    /// </summary>
    public double VerticalOffset
    {
        get { return (double)GetValue(VerticalOffsetProperty); }
        set { SetValue(VerticalOffsetProperty, value); }
    }
    public static readonly DependencyProperty VerticalOffsetProperty =
        DependencyProperty.Register(
            "VerticalOffset",
            typeof(double),
            typeof(ScrollViewerOffsetMediator),
            new PropertyMetadata(OnVerticalOffsetChanged));
    public static void OnVerticalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var mediator = (ScrollViewerOffsetMediator)o;
        if (null != mediator.ScrollViewer)
        {
            mediator.ScrollViewer.ScrollToVerticalOffset((double)(e.NewValue));
        }
    }

    /// <summary>
    /// HorizontalOffset property to forward to the ScrollViewer.
    /// </summary>
    public double HorizontalOffset
    {
        get { return (double)GetValue(HorizontalOffsetProperty); }
        set { SetValue(VerticalOffsetProperty, value); }
    }
    public static readonly DependencyProperty HorizontalOffsetProperty =
        DependencyProperty.Register(
            "HorizontalOffset",
            typeof(double),
            typeof(ScrollViewerOffsetMediator),
            new PropertyMetadata(OnHorizontalOffsetChanged));
    public static void OnHorizontalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var mediator = (ScrollViewerOffsetMediator)o;
        if (null != mediator.ScrollViewer)
        {
            mediator.ScrollViewer.ScrollToHorizontalOffset((double)(e.NewValue));
        }
    }

    /// <summary>
    /// Multiplier for ScrollableHeight property to forward to the ScrollViewer.
    /// </summary>
    /// <remarks>
    /// 0.0 means "scrolled to top"; 1.0 means "scrolled to bottom".
    /// </remarks>
    public double ScrollableHeightMultiplier
    {
        get { return (double)GetValue(ScrollableHeightMultiplierProperty); }
        set { SetValue(ScrollableHeightMultiplierProperty, value); }
    }
    public static readonly DependencyProperty ScrollableHeightMultiplierProperty =
        DependencyProperty.Register(
            "ScrollableHeightMultiplier",
            typeof(double),
            typeof(ScrollViewerOffsetMediator),
            new PropertyMetadata(OnScrollableHeightMultiplierChanged));
    public static void OnScrollableHeightMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var mediator = (ScrollViewerOffsetMediator)o;
        var scrollViewer = mediator.ScrollViewer;
        if (null != scrollViewer)
        {
            scrollViewer.ScrollToVerticalOffset((double)(e.NewValue) * scrollViewer.ScrollableHeight);
            if (((double)e.NewValue == 0) && ((double)e.OldValue == 1))
            {
                Debug.WriteLine("[1] {0:HH:mm:ss.fff} ScrollableHeightMultiplier 1 => 0 ", DateTime.Now);
            }
        }
    }


    /// <summary>
    /// Multiplier for ScrollableWidth property to forward to the ScrollViewer.
    /// </summary>
    /// <remarks>
    /// 0.0 means "scrolled to top"; 1.0 means "scrolled to bottom".
    /// </remarks>
    public double ScrollableWidthMultiplier
    {
        get { return (double)GetValue(ScrollableWidthMultiplierProperty); }
        set { SetValue(ScrollableWidthMultiplierProperty, value); }
    }
    public static readonly DependencyProperty ScrollableWidthMultiplierProperty =
        DependencyProperty.Register(
            "ScrollableWidthMultiplier",
            typeof(double),
            typeof(ScrollViewerOffsetMediator),
            new PropertyMetadata(OnScrollableWidthMultiplierChanged));
    public static void OnScrollableWidthMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var mediator = (ScrollViewerOffsetMediator)o;
        var scrollViewer = mediator.ScrollViewer;
        if (null != scrollViewer)
        {
            scrollViewer.ScrollToHorizontalOffset((double)(e.NewValue) * scrollViewer.ScrollableWidth);
        }
    }    
}

0 个答案:

没有答案