WPF通过子容器滚动父容器

AXG*_*010 3 wpf xaml scrollview

我在尝试弄清楚如何滚动包含在滚动查看器内的网格内容时遇到了一些问题.当尝试使用鼠标滚轮或平移(使用触摸屏)滚动时,如果鼠标/触摸点位于空白区域上,则网格会滚动,但如果它高于某些控件(例如,组合框)则会赢得"滚动.是否有一些我缺少的属性允许子面板允许它们滚动它们的父容器?

编辑: 我错误地说明了我原来的布局.这是我的senario的简化版本:

<Grid>
    <ScrollViewer Name="MainScrollViewer">
        <StackPanel>
            <ListBox />    <--Doesn't Scroll-->
            <Button />     <--Scrolls Fine-->
            <TextBlock />  <--Scrolls Fine-->
            <TextBox />    <--Scrolls Fine-->
            <DataGrid />   <--Doesn't Scroll-->
        </StackPanel>
    </ScrollViewer>
</Grid>
Run Code Online (Sandbox Code Playgroud)

一位同事指出我的问题是由于ListBoxes和DataGrids等控件本身包含ScrollViewers,这是有道理的.他的建议(可行,但我们都同意似乎比它应该更复杂)是捕获并重新抛出后面代码中的滚动事件(并且可能必须处理计算滚动的偏移量)以便它可以冒泡到"MainScrollViewer".

编辑2: 似乎实现此目的的唯一方法是使用后台代码来处理父级中的PreviewMouseWheel事件.这是有效的,但我如何实现相同的平移(用手指在触摸屏上滚动)?

Dea*_*uga 6

使用 ScrollViewer 的 PreviewMouseWheel 事件和 ScrollToVerticalOffset 方法...

private void ScrollViewerOnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    var scv = sender as ScrollViewer;
    if (scv == null) return;
    scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
    e.Handled = true;
}
Run Code Online (Sandbox Code Playgroud)


Ill*_*dan 5

为您的scrollview创建一个冒泡的scrollbehavior:

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

public sealed class BubbleScrollEvent : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;
        base.OnDetaching();
    }

    void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (!e.Handled)
        {
            e.Handled = true;
            var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) { RoutedEvent = UIElement.MouseWheelEvent };
            AssociatedObject.RaiseEvent(e2);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将此行为添加到您的scrollviewer:

 <ScrollViewer x:Name="Scroller">
                    <i:Interaction.Behaviors>
                        <ViewAddons:BubbleScrollEvent />
                    </i:Interaction.Behaviors>
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是比标记答案更清晰的方法.更可重复使用. (2认同)