2009-12-17 6 views
5

У меня есть scrollviewer, обертывающий древовидную структуру.Прокрутка к выбранному Treeviewitem в scrollview

Я заполняю древовидное изображение программным способом (оно не связано) и разворачивает древовидную структуру до заданного древовидного элемента. Все работает отлично.

Моя проблема заключается в том, что когда дерево расширяется, мне нужно, чтобы scrollview родило дерево, чтобы прокрутить до дерева, который я только что расширил. Есть идеи? - Имейте в виду, что древовидная структура может не иметь одинаковой структуры каждый раз, когда она расширяется, поэтому правила просто сохраняют текущую позицию прокрутки и реселлинг до этого ...

ответ

4

У меня была такая же проблема, TreeView не прокручивает выбранный элемент.

Что я сделал, после расширения дерева на выбранный TreeViewItem я вызвал метод Помощник диспетчера, чтобы разрешить обновлять пользовательский интерфейс, а затем использовал TransformToAncestor для выбранного элемента, чтобы найти его положение в ScrollViewer. Вот код:

// 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); 

Вот код 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

Спасибо! Это отлично поработало. Должен был знать, что предметы должны быть «визуализированы» сначала! –

+0

Кажется, что offet.Y относительно, поэтому myScroll.ScrollToVerticalOffset (offset.Y); необходимо изменить на sv.ScrollToVerticalOffset (offset.Y + sv.VerticalOffset); –

2

ScrollViewer трюк Джейсона это отличный способ перемещения TreeViewItem в определенной позиции.

Одна проблема: хотя в MVVM у вас нет доступа к ScrollViewer в модели представления. В любом случае, это способ добраться до него. Если у вас есть TreeViewItem, вы можете подойти к его визуальному дереву, пока не достигнете встроенного ScrollViewer:

// Get the TreeView's ScrollViewer 
DependencyObject parent = VisualTreeHelper.GetParent(selectedTreeViewItem); 
while (parent != null && !(parent is ScrollViewer)) 
{ 
    parent = VisualTreeHelper.GetParent(parent); 
} 
Смежные вопросы