【问题标题】:WPF - Content inside a ScrollViewer element does not touch-scroll when touching a child DataGridWPF - ScrollViewer 元素内的内容在触摸子 DataGrid 时不会触摸滚动
【发布时间】:2016-01-14 14:24:07
【问题描述】:

使用以下 XAML:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="600" Width="640">
<ScrollViewer PanningMode="Both">
    <StackPanel>
        <TextBlock TextWrapping="Wrap">LOTS OF TEXT...</TextBlock>
        <DataGrid MinHeight="200">
                <DataGrid.Columns>
                    <DataGridTextColumn Width="100"></DataGridTextColumn>
                    <DataGridTextColumn Width="100"></DataGridTextColumn>
                    <DataGridTextColumn Width="100"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
        <TextBlock TextWrapping="Wrap">LOTS OF TEXT...</TextBlock>
    </StackPanel>
</ScrollViewer>
</Window>

您可以通过触摸TextBlocks 进行滚动。但是,如果您触摸DataGrid 并尝试滚动,它什么也不做。

我猜这与 DataGrid 中的内容本身可能是可滚动的这一事实有关,因此 WPF 与潜在的嵌套滚动条混淆了。

所需的行为是触摸DataGrid 将首先滚动DataGrid 中的内容(如有必要)。然后,当DataGrid 中的内容完全滚动时,主窗口将滚动。

【问题讨论】:

  • DataGrid 内部有ScrollViewer,它自己捕获所有滚动事件。您将不得不冒泡相应的事件,请参阅以了解如何为 MouseWheelListView here 完成它。
  • 谢谢@Sinatr。该代码确实适用于PreviewMouseWheel。然而,奇怪的是,它似乎不适用于触摸事件。我为PreviewTouchDownPreviewTouchMovePreviewTouchUp 做了类似的事情,而顶层ScrollViewer 仍然没有滚动。
  • 实际上,如果您只是在两个滚动查看器上为 hittestvisibility 打一个 Background=Transparent,它应该会自动滚动链接。我从来不需要在任何地方实际冒泡任何东西,而且在新的东西中它变得更加容易,你可以通过属性切换滚动链。

标签: c# wpf xaml datagrid touch


【解决方案1】:

与 PreviewMouseWheel (Bubbling scroll events from a ListView to its parent) 类似,您也可以使用触控控制:

C#:

public sealed class SubControlsTouchScrollEvent : Behavior<UIElement>
{
    double originalDistance;
    double actualDistance;
    int delta;

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewTouchDown += AssociatedObject_PreviewTouchDown;
        AssociatedObject.PreviewTouchMove += AssociatedObject_PreviewTouchMove;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PreviewTouchUp -= AssociatedObject_PreviewTouchDown;
        AssociatedObject.PreviewTouchMove -= AssociatedObject_PreviewTouchMove;
        base.OnDetaching();
    }

    void AssociatedObject_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        System.Windows.IInputElement s = sender as System.Windows.IInputElement;
        originalDistance = e.GetTouchPoint(s).Position.Y;
    }

    void AssociatedObject_PreviewTouchMove(object sender, TouchEventArgs e)
    {
        ScrollViewer s = sender as ScrollViewer;
        actualDistance = e.GetTouchPoint(s).Position.Y;
        delta = Convert.ToInt16(actualDistance - originalDistance);          
        s.ScrollToVerticalOffset(s.VerticalOffset - (delta * 0.1));
        e.Handled = true;
    }
}

XAML:

<ScrollViewer PanningMode="Both" Background="Transparent">
   <interactivity:Interaction.Behaviors>
      <local:SubControlsTouchScrollEvent />
   </interactivity:Interaction.Behaviors>
</ScrollViewer>

注意:这仅适用于垂直滚动,但您可以以相同的方式添加水平滚动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多