He tenido el mismo problema, con el TreeView no se desplaza al elemento seleccionado.
Lo que hice fue, después de expandir el árbol al TreeViewItem seleccionado, invocar un método Dispatcher Helper para permitir que la UI se actualizara, y luego usé TransformToAncestor en el elemento seleccionado, para encontrar su posición dentro del ScrollViewer. Aquí está el código:
// 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);
Aquí está el código 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;
}
}
¡Gracias! Eso funcionó muy bien. ¡Debería haber sabido que los artículos necesitaban ser "visualizados" primero! –
Parece que offet.Y es relativo, por lo que myScroll.ScrollToVerticalOffset (offset.Y); necesita ser cambiado a sv.ScrollToVerticalOffset (offset.Y + sv.VerticalOffset); –