2009-12-17 12 views
5

Ho un scrollviewer che avvolge una vista ad albero.Scorrimento a Treeviewitem selezionato all'interno di una scrollview

Popolare la visualizzazione di albero a livello di codice (non è associato) ed espande la vista ad albero su un treeviewitem predeterminato. Tutto funziona bene

Il mio problema è che quando l'albero si espande mi piacerebbe la scrollview che i genitori della treeview scorrano fino al treeviewitem che ho appena espanso. Qualche idea? - tieni presente che la vista ad albero potrebbe non avere la stessa struttura ogni volta che viene espansa, in modo da escludere solo la posizione corrente di scorrimento e ripristinarla ...

risposta

4

Ho avuto lo stesso problema, con il TreeView non sta scorrendo fino all'elemento selezionato.

Ciò che ho fatto è stato, dopo aver espanso l'albero nel TreeViewItem selezionato, ho chiamato un metodo di supporto Dispatcher per consentire all'IU di aggiornare e quindi ho utilizzato TransformToAncestor sull'elemento selezionato per trovare la sua posizione all'interno di ScrollViewer. Ecco il codice:

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

Qui è il codice 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

Grazie! Ha funzionato alla grande Avrei dovuto sapere che gli elementi dovevano essere "visualizzati" prima! –

+0

Sembra che offet.Y sia relativo, quindi myScroll.ScrollToVerticalOffset (offset.Y); deve essere cambiato in sv.ScrollToVerticalOffset (offset.Y + sv.VerticalOffset); –

2

di Jason ScrollViewer trucco è un ottimo modo di spostare un TreeViewItem in una posizione specifica.

Un problema, tuttavia: in MVVM non si ha accesso a ScrollViewer nel modello di visualizzazione. Ecco un modo per arrivarci comunque. Se si dispone di un oggetto TreeViewItem, è possibile risalire il suo albero visivo fino a raggiungere lo ScrollViewer incorporato:

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