2010-01-19 30 views
5

Tôi có Chế độ xem và Chế độ xem trong Silverlight 3.0.Ràng buộc hai chiều thuộc tính VerticalOffset trên ScrollViewer?

Chế độ xem có chứa một ScrollViewer tiêu chuẩn, chứa nội dung động.

Tùy thuộc vào nội dung trong ScrollViewer, người dùng có thể đã cuộn xuống một nửa nội dung, và sau đó thực hiện một hành động khiến ScrollViewer tải nội dung mới, nhưng ScrollViewer không tự động cuộn lên trên cùng.

Tôi muốn có thể liên kết với thuộc tính VerticalOffset, nhưng nó là chỉ đọc. Bất kỳ ý tưởng nào về hành vi có thể đính kèm? Bất kỳ ý tưởng nào?

Cảm ơn.

+0

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

Trả lời

3

Vì bạn đang sử dụng một ViewModel tôi lấy nó là "hành động khiến ScrollViewer tải nội dung mới" là kết quả của những thay đổi được thực hiện bên trong hoặc cho ViewModel. Đó là trường hợp tôi sẽ thêm một sự kiện vào ViewModel được kích hoạt mỗi lần thay đổi đó xảy ra.

Chế độ xem của bạn có thể thêm trình xử lý sự kiện này và gọi ScrollToVerticalPosition trên ScrollViewer khi được kích hoạt.

4

Các bài viết trên blog sau đây cung cấp một hành vi kèm theo đó cho thấy nhiều/offsets ngang dọc của một ScrollViewer để bạn có thể liên kết với họ, hoặc cài đặt chúng trong mã:

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

Điều này cho phép đánh dấu sau :

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

Tôi muốn xem một bài viết (tôi cần giải pháp wpf để ràng buộc scrollviewer), nhưng liên kết là sai. – Sinatr

+0

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

+0

@Thomas cảm ơn - Tôi đã cập nhật liên kết – ColinE

0

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> 
Các vấn đề liên quan