WPF - 触摸子DataGrid时,ScrollViewer元素内的内容不会触摸滚动

时间:2016-01-14 14:24:08

标签: c# wpf xaml datagrid touch

使用以下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>

您可以触摸TextBlock进行滚动。但是,如果您触摸DataGrid并尝试滚动,则不执行任何操作。

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

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

1 个答案:

答案 0 :(得分: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>

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