我在使鼠标滚轮滚动以在以下XAML中工作时遇到问题,为简化起见,我对其进行了简化:

<ScrollViewer
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
CanContentScroll="False"
>
    <Grid
    MouseDown="Editor_MouseDown"
    MouseUp="Editor_MouseUp"
    MouseMove="Editor_MouseMove"
    Focusable="False"
    >
        <Grid.Resources>
            <DataTemplate
            DataType="{x:Type local:DataFieldModel}"
            >
                <Grid
                Margin="0,2,2,2"
                >
                    <TextBox
                    Cursor="IBeam"
                    MouseDown="TextBox_MouseDown"
                    MouseUp="TextBox_MouseUp"
                    MouseMove="TextBox_MouseMove"
                    />
                </Grid>
            </DataTemplate>
        </Grid.Resources>
        <ListBox
        x:Name="DataFieldListBox"
        ItemsSource="{Binding GetDataFields}"
        SelectionMode="Extended"
        Background="Transparent"
        Focusable="False"
        >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemContainerStyle>
                <Style
                TargetType="ListBoxItem"
                >
                    <Setter
                    Property="Canvas.Left"
                    Value="{Binding dfX}"
                    />
                    <Setter
                    Property="Canvas.Top"
                    Value="{Binding dfY}"
                    />
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</ScrollViewer>

在视觉上,结果是一个已知大小的区域,从集合中读取的DataField可以用具有任意位置,大小等的TextBox表示。如果ListBox的样式“区域”太大而无法一次显示,则可以进行水平和垂直滚动,但只能使用滚动条。

为了获得更好的人体工程学设计和合理性,应该可以滚动鼠标滚轮,通常ScrollViewer会自动处理它,但是ListBox似乎正在处理这些事件,因此父ScrollViewer永远不会看到它们。到目前为止,我只能通过为IsHitTestVisible=False或父ListBox设置Grid来进行滚轮滚动工作,但是此后子元素的鼠标事件当然都无法工作。

如何确保ScrollViewer看到鼠标滚轮事件,同时为其他人保留子元素?

编辑:我刚刚了解到ListBox具有内置的ScrollViewer,它可能会从父ScrollViewer窃取车轮事件,并且指定控制模板可以将其禁用。如果可以解决问题,我将更新此问题。

最佳答案

您还可以创建一个行为并将其附加到父控件(滚动事件应在其中进行冒泡)。

// Used on sub-controls of an expander to bubble the mouse wheel scroll event up
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)
    {
        e.Handled = true;
        var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
        e2.RoutedEvent = UIElement.MouseWheelEvent;
        AssociatedObject.RaiseEvent(e2);
    }
}

<SomePanel>
            <i:Interaction.Behaviors>
                <viewsCommon:BubbleScrollEvent />
            </i:Interaction.Behaviors>
</SomePanel>

关于wpf - scrollviewer的子元素阻止鼠标滚轮滚动?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14348517/

10-12 00:17
查看更多