DataGrids через ScrollViewer предотвращают прокрутку - PullRequest
3 голосов
/ 31 мая 2011

У меня есть несколько DataGrids, расположенных поверх ScrollViewer.Эти DataGrids имеют свойство «height: auto», так что я могу скрыть полосу прокрутки и просмотреть все содержимое.Единственная проблема заключается в том, что DataGrids фокусируется, и поэтому я не могу прокрутить ScrollViewer.Это свойство, позволяющее сосредоточиться на ScrollViewer, а также сохранить поведение DataGrids (чтобы я мог выбирать элементы)?

Спасибо!

Ответы [ 4 ]

6 голосов
/ 17 января 2013

Уже поздно, но я решил эту проблему следующим образом: Я создал событие PreviewMouseWheel для DataGrid и вручную прокручивал упаковку ScrollViewer

private void dgInvoicesItems_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
this.scrInvoice.ScrollToVerticalOffset(this.scrInvoice.ContentVerticalOffset - e.Delta);
}
3 голосов
/ 12 марта 2014

Я столкнулся с точно такой же проблемой, за исключением того, что мой сценарий был немного сложнее.Вместо того, чтобы использовать DataGrid в ScrollViewer, у меня в 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 от Страницы, которая будет их хранить, поэтому я обеспечу изоляцию кода и меньшедублированный код.И что еще лучше, я абсолютно использую тот факт, что RoutedEvents продолжает распространяться от Источника ко всем его родителям, пока кто-то не обработает его (в моем случае это мой ProductScrollViewer).

0 голосов
/ 29 марта 2017

TopMouseScrollPriorityBehavior.TopMouseScrollPriority

Вы можете просто установить следующее присоединенное свойство к своему ScrollViewer

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: пространство имен, содержащее это поведение

Поддержка касания

Чтобы включить поддержку касания, вы также можете установить для ScrollViewer.PanningMode значениеNone на вашем DataGrid и установите то же свойство на VerticalFirst или другое значение на верхнем уровне ScrollViewer

Пример

<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="5" PanningMode="VerticalFirst">
    <DataGrid ScrollViewer.PanningMode="None" ItemsSource="{Binding Items}" />
</ScrollViewer>
0 голосов
/ 31 мая 2011

Попробуйте установить для параметра CanContentScroll в DataGrid значение False, например:

<DataGrid ScrollViewer.CanContentScroll="False" ... />
...