ScrollViewer上的VerticalOffset属性的双向绑定?

问题描述:

我在Silverlight 3.0中有一个View和一个ViewModel。ScrollViewer上的VerticalOffset属性的双向绑定?

该视图包含一个标准的ScrollViewer,其中包含动态内容。

根据ScrollViewer中的内容,用户可能会滚动到内容的中间位置,然后执行一个操作,导致ScrollViewer加载新内容,但ScrollViewer不会自动滚动到顶部。

我希望能够绑定到VerticalOffset属性,但它是只读的。关于可附着行为的任何想法? 任何想法?

谢谢。

+0

要公开在视图模型一个属性,它指示了ScrollViewer应该是?它不清楚你想要将VerticalOffset绑定到什么? – AnthonyWJones 2010-01-19 21:24:53

由于您使用的是视图模型我把它叫做“行动导致的ScrollViewer加载新的内容”里面或视图模型所做的更改的结果。在这种情况下,我会向ViewModel添加一个事件,每次发生这种变化时都会触发该事件。此事件

您的视图可以添加一个处理程序,并调用ScrollToVerticalPosition在ScrollViewer中其发射时。

以下博客文章提供了一个附加的行为,它公开的ScrollViewer的垂直/水平偏移,以便可以结合到它们,或将它们设置在代码:

http://blog.scottlogic.com/2010/07/21/exposing-and-binding-to-a-silverlight-scrollviewers-scrollbars.html

这允许以下标记:

<ScrollViewer 
    local:ScrollViewerBinding.VerticalOffset="{Binding YPosition, Mode=TwoWay}" 
    local:ScrollViewerBinding.HorizontalOffset="{Binding XPosition, Mode=TwoWay}"> 
    <!-- Big content goes here! --> 
</ScrollViewer> 
+0

我想看一篇文章(我需要wpf解决方案来绑定scrollviewer),但链接是错误的。 – Sinatr 2016-02-01 13:48:16

+0

http://blog.scottlogic.com/2010/07/21/exposing-and-binding-to-a-silverlight-scrollviewers-scrollbars.html – Thomas 2016-02-11 14:00:14

+0

@Thomas感谢 - 我已经更新的链接 – ColinE 2016-02-11 17:18:58

我简化了@ColinE的解决方案。而不是挂在ScrollBar.ValueChanged事件,我钩到ScrollViewer.ScrollChanged事件。因此,1。没有必要找到在视觉树ScrollBar和2 ScrollBar.ValueChanged就是所谓的一些过渡态时的ScrollViewer变化的内容和我不希望赶上这些国家。

我后我的代码为VerticalOffset,该HorizontalOffset是相似的:

/// <summary> 
/// VerticalOffset attached property 
/// </summary> 
public static readonly DependencyProperty VerticalOffsetProperty = 
    DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), 
    typeof(ScrollViewerBinding), new FrameworkPropertyMetadata(double.NaN, 
     FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
     OnVerticalOffsetPropertyChanged)); 
      OnVerticalOffsetPropertyChanged)); 

/// <summary> 
/// Just a flag that the binding has been applied. 
/// </summary> 
private static readonly DependencyProperty VerticalScrollBindingProperty = 
    DependencyProperty.RegisterAttached("VerticalScrollBinding", typeof(bool?), typeof(ScrollViewerBinding)); 

public static double GetVerticalOffset(DependencyObject depObj) 
{ 
    return (double)depObj.GetValue(VerticalOffsetProperty); 
} 

public static void SetVerticalOffset(DependencyObject depObj, double value) 
{ 
    depObj.SetValue(VerticalOffsetProperty, value); 
} 

private static void OnVerticalOffsetPropertyChanged(DependencyObject d, 
    DependencyPropertyChangedEventArgs e) 
{ 
    ScrollViewer scrollViewer = d as ScrollViewer; 
    if (scrollViewer == null) 
     return; 

    BindVerticalOffset(scrollViewer); 
    scrollViewer.ScrollToVerticalOffset((double)e.NewValue); 
} 

public static void BindVerticalOffset(ScrollViewer scrollViewer) 
{ 
    if (scrollViewer.GetValue(VerticalScrollBindingProperty) != null) 
     return; 

    scrollViewer.SetValue(VerticalScrollBindingProperty, true); 
    scrollViewer.ScrollChanged += (s, se) => 
    { 
     if (se.VerticalChange == 0) 
      return; 
     SetVerticalOffset(scrollViewer, se.VerticalOffset); 
    }; 
} 

而且用它在XAML:

<ScrollViewer local:ScrollViewerBinding.VerticalOffset="{Binding ScrollVertical}"> 
    <!-- content ... --> 
</ScrollViewer>