WPF如何从TreeView中移除ScrollViewer

18

我想知道是否可以轻松地关闭TreeView的ScrollViewer。

我有一个带有网格的UserControl。其中一格包含几个TreeView放在Stackpanel中。控件的高度根据TreeViews的高度自动调整,因此不需要滚动条。

问题是:我有很多这样的UserControl在ListBox中,并带有自己的ScrollViewer,但当使用鼠标滚轮时,在TreeView上停止滚动。

这是因为TreeView有它自己的ScrollViewer,它会窃取鼠标滚轮事件。我知道这可能通过重写控件模板来实现,但我希望有更简单的方法。

1个回答

45
你可以使用这里描述的技术: http://serialseb.blogspot.com/2007/09/wpf-tips-6-preventing-scrollviewer-from.html 来阻止滚轮事件被 ScrollViewer 处理。将 PreviewMouseWheel="HandlePreviewMouseWheel" 添加到你的 TreeView 中,并定义 HandlePreviewMouseWheel 为:
private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    if (!e.Handled)
    {
        e.Handled = true;
        var eventArg = new MouseWheelEventArgs(
            e.MouseDevice, e.Timestamp, e.Delta);
        eventArg.RoutedEvent = UIElement.MouseWheelEvent;
        eventArg.Source = sender;
        var parent = ((Control)sender).Parent as UIElement;
        parent.RaiseEvent(eventArg);
    }
}

将控件模板更改为不包含ScrollViewer并不难,因为TreeView的默认模板非常简单,大部分复杂性都涉及到处理ScrollViewer。尝试做这个:

<TreeView.Template>
    <ControlTemplate TargetType="TreeView">
        <Border BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                SnapsToDevicePixels="true">
            <ItemsPresenter/>
        </Border>
    </ControlTemplate>
</TreeView.Template>

嗯,看来我的上一条评论没有起作用。不管怎样,谢谢!我都试过了。XAML控件模板完美地解决了问题,但是在滚动时,预览鼠标滚轮仍然会有几次“卡住”的情况。我将采用XAML解决方案。 - user380527
8
对于 XAML 解决方案的支持加一分(同样适用于相同的问题)。 - JanW
非常好。我使用了这个处理程序以及EventManager.RegisterClassHandler来消除订阅所有相同类型的控件以解决问题的需要。 - N. Kudryavtsev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接