ScrollViewer上VerticalOffset属性的双向绑定?

我在Silverlight 3.0中有一个View和一个ViewModel。

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

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

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

谢谢。

以下博客文章提供了一个附加行为,它公开了scrollviewer的垂直/水平偏移,以便您可以绑定它们,或者在代码中设置它们:

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

这允许以下标记:

   

由于您正在使用ViewModel,因此我认为“导致ScrollViewer加载新内容的操作”是在ViewModel内部或对ViewModel进行更改的结果。 在这种情况下,我会向ViewModel添加一个事件,每次发生这样的更改时都会触发该事件。

您的View可以在此事件上添加处理程序,并在ScrollViewer触发时调用ScrollToVerticalPosition。

我简化了@ColinE的解决方案。 我挂钩到ScrollViewer.ScrollChanged事件,而不是挂钩到ScrollBar.ValueChanged事件。 因此,1。没有必要在可视化树中找到ScrollBar和2.当ScrollViewer的内容发生变化并且我不想捕获这些状态时, ScrollBar.ValueChanged在某些过渡状态中被调用。

我发布了VerticalOffset代码, HorizontalOffset类似:

 ///  /// VerticalOffset attached property ///  public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerBinding), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnVerticalOffsetPropertyChanged)); OnVerticalOffsetPropertyChanged)); ///  /// Just a flag that the binding has been applied. ///  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中使用它: