Tôi đã đơn giản hóa giải pháp của @ ColinE. Thay vì hooking vào sự kiện ScrollBar.ValueChanged
, tôi móc đến sự kiện ScrollViewer.ScrollChanged
. Vì vậy, 1. nó không phải là cần thiết để tìm các ScrollBar
trong cây thị giác và 2. ScrollBar.ValueChanged
được gọi là trong một số trạng thái chuyển tiếp khi nội dung của các thay đổi ScrollViewer
và tôi không muốn bắt những trạng thái này.
tôi gửi mã của tôi cho VerticalOffset
, các HorizontalOffset
cũng tương tự như:
/// <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);
};
}
Và sử dụng nó trong XAML:
<ScrollViewer local:ScrollViewerBinding.VerticalOffset="{Binding ScrollVertical}">
<!-- content ... -->
</ScrollViewer>
Bạn muốn để lộ một tài sản trên ViewModel cho biết vị trí ScrollViewer nên? Nó không rõ ràng những gì bạn sẽ muốn ràng buộc các VerticalOffset đến? – AnthonyWJones