ScrollViewer上的DataGrid阻止其滚动

问题描述

| 我在ScrollViewer上放置了多个DataGrid。 这些DataGrid具有一个“高度:自动属性,因此我可以隐藏滚动条并查看所有内容。 唯一的问题是DataGrids占据了焦点,因此我无法滚动ScrollViewer。 这是一个使焦点始终集中在ScrollViewer上但又保持DataGrids行为(以便我可以选择元素)的属性吗? 谢谢 !     

解决方法

        我遇到了完全相同的问题,只不过我的情况有些复杂。我没有在ScrollViewer中使用DataGrid,而是在ScrollViewer中使用了一堆UserControl(称为ProductDataGrid,定义如下): ProductDataGrid.xaml:
<UserControl x:Class=\"My.Control.ProductDataGrid\" ...>
    <Grid>
        <Grid.RowDefinitions>...</Grid.RowDefinitions>

        <TextBlock x:Name=\"Header\" Grid.Row=\"0\" ... />

        <DataGrid x:Name=\"ProductData\" Grid.Row=\"1\" ... />
    </Grid>
</UserControl>
ProductPortfolioListView.xaml:
<Page ...
      xmlns:my=\"clr-namespace:My.Control\"
      ....>
    <Grid>
        <Grid.RowDefinitions>...</Grid.RowDefinitions>

        <ScrollViewer x:Name=\"ProductScrollViewer\">
            <StackPanel>
                <my:ProductDataGrid ... />

                <my:ProductDataGrid ... />

                <my:ProductDataGrid ... />
            </StackPanel>
        </ScrollViewer>
Livsi提供的解决方案是正确的,但是我的UserControl无法访问我的ScrollViewer,所以这是我的解决方案: ProductPortfolioListView.xaml:
<Page ...
      xmlns:my=\"clr-namespace:My.Control\"
      ....>
    <Grid>
        <Grid.RowDefinitions>...</Grid.RowDefinitions>

        <ScrollViewer x:Name=\"ProductScrollViewer\">
            <StackPanel>
                <my:ProductDataGrid ... 
                        PreviewMouseWheel=\"ProductDataGrid_PreviewMouseWheel\" />

                <my:ProductDataGrid ... 
                        PreviewMouseWheel=\"ProductDataGrid_PreviewMouseWheel\" />

                <my:ProductDataGrid ... 
                        PreviewMouseWheel=\"ProductDataGrid_PreviewMouseWheel\" />
            </StackPanel>
        </ScrollViewer>
ProductPortfolioListView.xaml.cs:
void ProductDataGrid_PreviewMouseWheel(object sender,MouseWheelEventArgs args)
{
    ProductScrollViewer.ScrollToVerticalOffset(ProductScrollViewer.ContentVerticalOffset - args.Delta;
    args.Handled = true;
}
注意,此解决方案的优点在于,我可以将DataGrid与保存它们的Page分开,因此可以实现代码隔离以及减少重复代码。甚至更好的是,我绝对利用了RoutedEvents不断从Source传播到其所有父项的事实,直到有人处理它为止(在我的情况下是我的ProductScrollViewer)。     ,        到了很晚,但是我以这种方式解决了这个问题: 我为DataGrid创建了PreviewMouseWheel事件 并手动滚动包装的ScrollViewer
private void dgInvoicesItems_PreviewMouseWheel(object sender,MouseWheelEventArgs e)
{
this.scrInvoice.ScrollToVerticalOffset(this.scrInvoice.ContentVerticalOffset - e.Delta);
}
    ,        TopMouseScrollPriorityBehavior.TopMouseScrollPriority 您只需将以下附加属性设置为set5ѭ
public class TopMouseScrollPriorityBehavior
{
    public static bool GetTopMouseScrollPriority(DependencyObject obj)
    {
        return (bool)obj.GetValue(TopMouseScrollPriorityProperty);
    }

    public static void SetTopMouseScrollPriority(DependencyObject obj,bool value)
    {
        obj.SetValue(TopMouseScrollPriorityProperty,value);
    }

    public static readonly DependencyProperty TopMouseScrollPriorityProperty =
        DependencyProperty.RegisterAttached(\"TopMouseScrollPriority\",typeof(bool),typeof(TopMouseScrollPriorityBehavior),new PropertyMetadata(false,OnPropertyChanged));

    private static void OnPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        var scrollViewer = d as ScrollViewer;
        if (scrollViewer == null)
            throw new InvalidOperationException($\"{nameof(TopMouseScrollPriorityBehavior)}.{nameof(TopMouseScrollPriorityProperty)} can only be applied to controls of type {nameof(ScrollViewer)}\");
        if (e.NewValue == e.OldValue)
            return;
        if ((bool)e.NewValue)
            scrollViewer.PreviewMouseWheel += ScrollViewer_PreviewMouseWheel;
        else
            scrollViewer.PreviewMouseWheel -= ScrollViewer_PreviewMouseWheel;
    }

    private static void ScrollViewer_PreviewMouseWheel(object sender,System.Windows.Input.MouseWheelEventArgs e)
    {
        var scrollViewer = (ScrollViewer)sender;
        scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta);
        e.Handled = true;
    }
}
用法
<ScrollViewer b:TopMouseScrollPriorityBehavior.TopMouseScrollPriority=\"True\" VerticalScrollBarVisibility=\"Auto\" Margin=\"5\" PanningMode=\"VerticalFirst\">
    <DataGrid ScrollViewer.PanningMode=\"None\" ItemsSource=\"{Binding Items}\" />
</ScrollViewer>
其中b:是包含此行为的名称空间 触摸支持 为了启用触摸支持,您可能还希望在
DataGrid
上将
ScrollViewer.PanningMode
设置为
None
,并将相同属性设置为
VerticalFirst
或在顶层
ScrollViewer
上设置其他值 例
<ScrollViewer VerticalScrollBarVisibility=\"Auto\" Margin=\"5\" PanningMode=\"VerticalFirst\">
    <DataGrid ScrollViewer.PanningMode=\"None\" ItemsSource=\"{Binding Items}\" />
</ScrollViewer>
    ,        尝试将DataGrid上的CanContentScroll设置为False,如下所示:
<DataGrid ScrollViewer.CanContentScroll=\"False\" ... />