滚动到滚动视图中选定的 Treeviewitem

发布于 2024-08-14 23:13:12 字数 184 浏览 7 评论 0原文

我有一个滚动查看器包装树视图。

我以编程方式填充树视图(未绑定),并将树视图扩展到预定的树视图项。一切都很好。

我的问题是,当树展开时,我希望作为树视图父级的滚动视图滚动到我刚刚展开的树视图项。有什么想法吗? - 请记住,树视图每次展开时可能不会具有相同的结构,因此排除了仅存储当前滚动位置并重置为该位置的情况......

I have a scrollviewer wrapping a treeview.

I populate the treeview programmatically (it is not bound), and expand the treeview to a predetermined treeviewitem. That all works fine.

My problem is that when the tree expands I would like the scrollview that parents the treeview to scroll to the treeviewitem that I just expanded. Any ideas? - keep in mind that the treeview may not have the same structure each time it is expanded, so that rules out just storing the current scroll position and reseting to that...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅过去的我 2024-08-21 23:13:12

我遇到了同样的问题,TreeView 没有滚动到所选项目。

我所做的是,在将树展开到选定的 TreeViewItem 后,我调用 Dispatcher Helper 方法来允许 UI 更新,然后在选定的项目上使用 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;
    }
}

I've had the same issue, with the TreeView not scrolling to the selected item.

What I did was, after expanding the tree to the selected TreeViewItem, I called a Dispatcher Helper method to allow the UI to update, and then used the TransformToAncestor on the selected item, to find its position within the ScrollViewer. Here is the code:

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

Here is the DispatcherHelper code:

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;
    }
}
晨敛清荷 2024-08-21 23:13:12

Jason 的 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);
}

Jason's ScrollViewer trick is a great way of moving a TreeViewItem to a specific position.

One problem, though: in MVVM you do not have access to the ScrollViewer in the view model. Here is a way to get to it anyway. If you have a TreeViewItem, you can walk up its visual tree until you reach the embedded ScrollViewer:

// Get the TreeView's ScrollViewer
DependencyObject parent = VisualTreeHelper.GetParent(selectedTreeViewItem);
while (parent != null && !(parent is ScrollViewer))
{
    parent = VisualTreeHelper.GetParent(parent);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文