问题起因:在一个用户控件里放置了1个TreeView垂直顺序放置。 当用户控件中的内容超过面板大小时,滚动条会自动出现 ,但是只有当鼠标指示在右边滚动条的那一条位置时,才支持鼠标滚轴滚动。 点在控件内部时滚轴无效。
问题分析:由于设置了d:designheight,自定义控件的宽高都是随着父容器的变化而变化的,于是我将Height设为较小的固定高度时,发现鼠标停留在控件内容时,滚轮控制滚动条滚动是有效的。这就说明UI上显示的滚动条并非是这个自定义控件的,而是这个自定义控件所在的父容器的,这样也解释了为什么之前在内容上滚动无效,但是在滚动条上是可以滚动的原因,然后接下来就好办了。代码如下:
//在构造函数中绑定treeview的鼠标滚轮事件,原因是在xmal前台绑定时触发不了MouseWheel事件 public TreeViewList() { InitializeComponent(); treeview.AddHandler(TreeView.MouseWheelEvent, new MouseWheelEventHandler(treeview_MouseWheel), true); } //根据父控件对象查找指定类型的子控件 private T GetVisualChild<T>(DependencyObject parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < numVisuals; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T; if (child == null) { child = GetVisualChild<T>(v); } if (child != null) { break; } } return child; } private void treeview_MouseWheel(object sender, MouseWheelEventArgs e) { //在treeview的基础上,层层查找,直到找到它的父容器,是个NavToolbar(滚动条是NavToolbar的滚动条,并非treeview的) try { var scroll = GetVisualChild<ScrollViewer>( ((((((((treeview.Parent as Grid).Parent as ChapterList).Parent as Grid).Parent as ScrollViewer). Parent as Border).Parent as Grid).Parent as Grid).Parent as Border).Parent); if (scroll != null) { scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta); } } catch (Exception) { } }