2009-12-17 3 views
5

Tôi có một scrollviewer gói một treeview.Cuộn đến Treeviewitem đã chọn trong một scrollview

Tôi phổ biến phần tử treeview theo chương trình (nó không bị ràng buộc) và mở rộng ảnh treeview thành một ảnh treeviewitem được xác định trước. Tất cả đều hoạt động tốt.

Vấn đề của tôi là khi cây mở rộng, tôi muốn scrollview rằng cha mẹ các ảnh tre để cuộn đến treeviewitem mà tôi vừa mở rộng. Bất kỳ ý tưởng? - Hãy nhớ rằng các ảnh tre có thể không có cấu trúc giống nhau mỗi khi nó được mở rộng, để các quy tắc chỉ lưu trữ vị trí cuộn hiện tại và đặt lại ...

Trả lời

4

Tôi đã có cùng một vấn đề, với TreeView không di chuyển đến mục đã chọn.

Điều tôi đã làm là sau khi mở rộng cây tới TreeViewItem đã chọn, tôi đã gọi phương thức Bộ điều phối cho phép giao diện người dùng cập nhật và sau đó sử dụng TransformToAncestor trên mục đã chọn để tìm vị trí của nó trong ScrollViewer. Đây là mã:

// Allow UI Rendering to Refresh 
    DispatcherHelper.WaitForPriority(); 

    // Scroll to selected Item 
    TreeViewItem tvi = myTreeView.SelectedItem as TreeViewItem; 
    Point offset = tvi.TransformToAncestor(myScroll).Transform(new Point(0, 0)); 
    myScroll.ScrollToVerticalOffset(offset.Y); 

đây là đoạn code DispatcherHelper:

public class DispatcherHelper 
{ 
    private static readonly DispatcherOperationCallback exitFrameCallback = ExitFrame; 

    /// <summary> 
    /// Processes all UI messages currently in the message queue. 
    /// </summary> 
    public static void WaitForPriority() 
    { 
     // Create new nested message pump. 
     DispatcherFrame nestedFrame = new DispatcherFrame(); 

     // Dispatch a callback to the current message queue, when getting called, 
     // this callback will end the nested message loop. 
     // The priority of this callback should be lower than that of event message you want to process. 
     DispatcherOperation exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(
      DispatcherPriority.ApplicationIdle, exitFrameCallback, nestedFrame); 

     // pump the nested message loop, the nested message loop will immediately 
     // process the messages left inside the message queue. 
     Dispatcher.PushFrame(nestedFrame); 

     // If the "exitFrame" callback is not finished, abort it. 
     if (exitOperation.Status != DispatcherOperationStatus.Completed) 
     { 
      exitOperation.Abort(); 
     } 
    } 

    private static Object ExitFrame(Object state) 
    { 
     DispatcherFrame frame = state as DispatcherFrame; 

     // Exit the nested message loop. 
     frame.Continue = false; 
     return null; 
    } 
} 
+0

Cảm ơn! Điều đó làm việc tuyệt vời. Nên biết rằng các mục cần được "hình dung" trước tiên! –

+0

Có vẻ như offet.Y là tương đối, vì vậy myScroll.ScrollToVerticalOffset (offset.Y); cần phải được thay đổi thành sv.ScrollToVerticalOffset (offset.Y + sv.VerticalOffset); –

2

ScrollViewer lừa Jason là một cách tuyệt vời của việc di chuyển một TreeViewItem đến một vị trí cụ thể.

Một vấn đề, mặc dù: trong MVVM bạn không có quyền truy cập vào ScrollViewer trong mô hình chế độ xem. Đây là một cách để có được nó anyway. Nếu bạn có TreeViewItem, bạn có thể đi lên cây hình ảnh của mình cho đến khi bạn đến được ScrollViewer được nhúng:

// Get the TreeView's ScrollViewer 
DependencyObject parent = VisualTreeHelper.GetParent(selectedTreeViewItem); 
while (parent != null && !(parent is ScrollViewer)) 
{ 
    parent = VisualTreeHelper.GetParent(parent); 
}