ScrollViewer上VerticalOffset属性的双向绑定?
我在Silverlight 3.0中有一个View和一个ViewModel。
该视图包含一个标准的ScrollViewer,其中包含动态内容。
根据ScrollViewer中的内容,用户可以向内滚动一半,然后执行导致ScrollViewer加载新内容的操作,但ScrollViewer不会自动滚动到顶部。
我希望能够绑定到VerticalOffset属性,但它是只读的。 关于可附加行为的任何想法? 有任何想法吗?
谢谢。
以下博客文章提供了一个附加行为,它公开了scrollviewer的垂直/水平偏移,以便您可以绑定它们,或者在代码中设置它们:
这允许以下标记:
由于您正在使用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中使用它: