Browse Source

Merge pull request #6342 from AvaloniaUI/improve-datagrid-scrolling

Improve datagrid scrolling
pull/6416/head
Max Katz 5 years ago
committed by GitHub
parent
commit
763d5f0f6d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      samples/ControlCatalog/Pages/DataGridPage.xaml
  2. 57
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  3. 10
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  4. 13
      src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs
  5. 6
      src/Avalonia.Controls.DataGrid/Themes/Default.xaml
  6. 6
      src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml

2
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -28,7 +28,7 @@
DockPanel.Dock="Top"/>
<DataGrid Name="dataGrid1" Margin="12" CanUserResizeColumns="True" CanUserReorderColumns="True" CanUserSortColumns="True" HeadersVisibility="All">
<DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" />
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" MinWidth="400" />
<!-- CompiledBinding example of usage. -->
<DataGridTextColumn Header="Region" Binding="{CompiledBinding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" />

57
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -25,6 +25,7 @@ using System.ComponentModel.DataAnnotations;
using Avalonia.Controls.Utils;
using Avalonia.Layout;
using Avalonia.Controls.Metadata;
using Avalonia.Input.GestureRecognizers;
namespace Avalonia.Controls
{
@ -2214,35 +2215,71 @@ namespace Avalonia.Controls
/// <param name="e">PointerWheelEventArgs</param>
protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
{
if (IsEnabled && !e.Handled && DisplayData.NumDisplayedScrollingElements > 0)
e.Handled = e.Handled || UpdateScroll(e.Delta * DATAGRID_mouseWheelDelta);
}
internal bool UpdateScroll(Vector delta)
{
if (IsEnabled && DisplayData.NumDisplayedScrollingElements > 0)
{
double scrollHeight = 0;
var delta = DATAGRID_mouseWheelDelta * e.Delta.Y;
var deltaAbs = Math.Abs(delta);
var handled = false;
var scrollHeight = 0d;
if (delta > 0)
// Vertical scroll handling
if (delta.Y > 0)
{
scrollHeight = Math.Max(-_verticalOffset, -deltaAbs);
scrollHeight = Math.Max(-_verticalOffset, -delta.Y);
}
else if (delta < 0)
else if (delta.Y < 0)
{
if (_vScrollBar != null && VerticalScrollBarVisibility == ScrollBarVisibility.Visible)
{
scrollHeight = Math.Min(Math.Max(0, _vScrollBar.Maximum - _verticalOffset), deltaAbs);
scrollHeight = Math.Min(Math.Max(0, _vScrollBar.Maximum - _verticalOffset), -delta.Y);
}
else
{
double maximum = EdgedRowsHeightCalculated - CellsHeight;
scrollHeight = Math.Min(Math.Max(0, maximum - _verticalOffset), deltaAbs);
scrollHeight = Math.Min(Math.Max(0, maximum - _verticalOffset), -delta.Y);
}
}
if (scrollHeight != 0)
{
DisplayData.PendingVerticalScrollHeight = scrollHeight;
handled = true;
}
// Horizontal scroll handling
if (delta.X != 0)
{
var originalHorizontalOffset = HorizontalOffset;
var horizontalOffset = originalHorizontalOffset - delta.X;
var widthNotVisible = Math.Max(0, ColumnsInternal.VisibleEdgedColumnsWidth - CellsWidth);
if (horizontalOffset < 0)
{
horizontalOffset = 0;
}
if (horizontalOffset > widthNotVisible)
{
horizontalOffset = widthNotVisible;
}
if (horizontalOffset != originalHorizontalOffset)
{
HorizontalOffset = horizontalOffset;
handled = true;
}
}
if (handled)
{
InvalidateRowsMeasure(invalidateIndividualElements: false);
e.Handled = true;
return true;
}
}
return false;
}
/// <summary>

10
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -173,7 +173,15 @@ namespace Avalonia.Controls
}
if (OwningRow != null)
{
e.Handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, ColumnIndex, OwningRow.Slot, !e.Handled);
var handled = OwningGrid.UpdateStateOnMouseLeftButtonDown(e, ColumnIndex, OwningRow.Slot, !e.Handled);
// Do not handle PointerPressed with touch,
// so we can start scroll gesture on the same event.
if (e.Pointer.Type != PointerType.Touch)
{
e.Handled = handled;
}
OwningGrid.UpdatedStateOnMouseLeftButtonDown = true;
}
}

13
src/Avalonia.Controls.DataGrid/Primitives/DataGridRowsPresenter.cs

@ -5,6 +5,9 @@
using System;
using System.Diagnostics;
using Avalonia.Input;
using Avalonia.Input.GestureRecognizers;
using Avalonia.Layout;
using Avalonia.Media;
@ -16,6 +19,11 @@ namespace Avalonia.Controls.Primitives
/// </summary>
public sealed class DataGridRowsPresenter : Panel
{
public DataGridRowsPresenter()
{
AddHandler(Gestures.ScrollGestureEvent, OnScrollGesture);
}
internal DataGrid OwningGrid
{
get;
@ -176,6 +184,11 @@ namespace Avalonia.Controls.Primitives
return new Size(totalCellsWidth + headerWidth, totalHeight);
}
private void OnScrollGesture(object sender, ScrollGestureEventArgs e)
{
e.Handled = e.Handled || OwningGrid.UpdateScroll(-e.Delta);
}
#if DEBUG
internal void PrintChildren()
{

6
src/Avalonia.Controls.DataGrid/Themes/Default.xaml

@ -247,7 +247,11 @@
<DataGridColumnHeader Name="PART_TopRightCornerHeader" Grid.Column="2"/>
<Rectangle Name="PART_ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" VerticalAlignment="Bottom" StrokeThickness="1" Height="1" Fill="{DynamicResource ThemeControlMidHighBrush}"/>
<DataGridRowsPresenter Name="PART_RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1" />
<DataGridRowsPresenter Name="PART_RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Column="2" Grid.Row="2" />
<Rectangle Name="BottomLeftCorner" Fill="{DynamicResource ThemeControlMidHighBrush}" Grid.Row="2" Grid.ColumnSpan="2" />
<ScrollBar Name="PART_VerticalScrollbar" Orientation="Vertical" Grid.Column="2" Grid.Row="1" Width="{DynamicResource ScrollBarThickness}"/>

6
src/Avalonia.Controls.DataGrid/Themes/Fluent.xaml

@ -601,7 +601,11 @@
<DataGridRowsPresenter Name="PART_RowsPresenter"
Grid.Row="1"
Grid.RowSpan="2"
Grid.ColumnSpan="3" />
Grid.ColumnSpan="3">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2"

Loading…
Cancel
Save