You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止UWP TreeView选中项时的自动垂直滚动行为

禁用UWP TreeView选中项自动滚动到视图中间的方案

你提到的WPF平台RequestBringIntoView事件拦截方案在UWP中不适用,是因为UWP没有暴露该事件的EventSetter支持。UWP平台下所有元素滚动到可视区域的逻辑,最终都是通过冒泡的BringIntoViewRequested路由事件触发的,直接拦截该事件即可禁用自动滚动行为,有两种可落地的实现方式:


方案1:自定义控件派生类(推荐,不影响手动调用滚动逻辑)

通过重写TreeViewItem的BringIntoView请求处理,禁用选中触发的默认滚动,不会影响你后续手动调用滚动接口的能力:

  • 自定义TreeViewItem容器类,拦截默认的BringIntoView处理逻辑
    public class DisableAutoScrollTreeViewItem : TreeViewItem
    {
        protected override void OnBringIntoViewRequested(BringIntoViewRequestedEventArgs e)
        {
            // 不执行基类逻辑,阻止默认滚动触发
            e.Handled = true;
        }
    }
    
  • 自定义TreeView类,替换默认的项容器生成逻辑
    public class DisableAutoScrollTreeView : TreeView
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new DisableAutoScrollTreeViewItem();
        }
    
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is DisableAutoScrollTreeViewItem;
        }
    }
    
  • 直接在XAML中替换原生TreeView为你自定义的DisableAutoScrollTreeView即可生效。

方案2:可视化树查找ScrollViewer拦截事件(无需自定义控件)

如果不想新增自定义控件类,可以在TreeView加载完成后,找到其内部封装的ScrollViewer控件,直接在ScrollViewer层面拦截冒泡的BringIntoView请求:

  • 给TreeView添加Loaded事件处理,在事件中查找内部ScrollViewer并拦截滚动请求
    private void TreeView_Loaded(object sender, RoutedEventArgs e)
    {
        // 查找TreeView内部的ScrollViewer
        ScrollViewer treeScrollViewer = FindVisualChild<ScrollViewer>(sender as TreeView);
        if (treeScrollViewer != null)
        {
            treeScrollViewer.BringIntoViewRequested += (_, args) =>
            {
                // 标记事件已处理,阻止自动滚动
                args.Handled = true;
            };
        }
    }
    
    // 可视化树子元素查找辅助方法
    private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
    {
        if (parent == null) return null;
        int childCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childCount; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);
            if (child is T target) return target;
            T childResult = FindVisualChild<T>(child);
            if (childResult != null) return childResult;
        }
        return null;
    }
    

注意:该方案会拦截所有流向该ScrollViewer的BringIntoView请求,包括你手动调用StartBringIntoView触发的滚动,如果需要保留手动滚动能力,建议使用方案1。


内容的提问来源于stack exchange,提问作者Badhan Sen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:24:25