Skip to content

Commit

Permalink
Merge pull request #321 from AvaloniaUI/fixes/horizontal-scroll-no-rows
Browse files Browse the repository at this point in the history
Fix horizontal scrollbar disappearing when rows removed
  • Loading branch information
grokys authored Dec 4, 2024
2 parents dab2346 + 56eff20 commit 1cd818d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,8 @@ private Rect EstimateViewport(Size availableSize)
{
if (!c.Bounds.Equals(default) && c.TransformToVisual(this) is Matrix transform)
{
return new Rect(0, 0, c.Bounds.Width, c.Bounds.Height)
.TransformToAABB(transform)
.Intersect(new(0, 0, double.PositiveInfinity, double.PositiveInfinity));
var r = new Rect(0, 0, c.Bounds.Width, c.Bounds.Height).TransformToAABB(transform);
return Intersect(r, new(0, 0, double.PositiveInfinity, double.PositiveInfinity));
}

c = c?.GetVisualParent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ protected override void UnrealizeElementOnItemRemoved(Control element)
ChildIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(element, ((TreeDataGridRow)element).RowIndex));
}

protected override Size MeasureOverride(Size availableSize)
{
var result = base.MeasureOverride(availableSize);

// If we have no rows, then get the width from the columns.
if (Columns is not null && (Items is null || Items.Count == 0))
result = result.WithWidth(Columns.GetEstimatedWidth(availableSize.Width));

return result;
}

protected override Size ArrangeOverride(Size finalSize)
{
Columns?.CommitActualWidths();
Expand Down
16 changes: 12 additions & 4 deletions tests/Avalonia.Controls.TreeDataGrid.Tests/TestTemplates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,20 @@ public static IControlTemplate TreeDataGridTemplate()
{
Children =
{
new TreeDataGridColumnHeadersPresenter
new ScrollViewer
{
Name = "PART_ColumnHeadersPresenter",
Name = "PART_HeaderScrollViewer",
Template = ScrollViewerTemplate(),
Height = 0,
HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
[DockPanel.DockProperty] = Dock.Top,
[!TreeDataGridColumnHeadersPresenter.ElementFactoryProperty] = x[!TreeDataGrid.ElementFactoryProperty],
[!TreeDataGridColumnHeadersPresenter.ItemsProperty] = x[!TreeDataGrid.ColumnsProperty],
Content = new TreeDataGridColumnHeadersPresenter
{
Name = "PART_ColumnHeadersPresenter",
[!TreeDataGridColumnHeadersPresenter.ElementFactoryProperty] = x[!TreeDataGrid.ElementFactoryProperty],
[!TreeDataGridColumnHeadersPresenter.ItemsProperty] = x[!TreeDataGrid.ColumnsProperty],
}.RegisterInNameScope(ns),
}.RegisterInNameScope(ns),
new ScrollViewer
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,69 @@ public void Can_Remove_Selected_Item_Sorted()
}
}

[AvaloniaFact(Timeout = 10000)]
public void Should_Show_Horizontal_ScrollBar()
{
var (target, items) = CreateTarget(columns:
[
new TextColumn<Model, int>("ID", x => x.Id, width: new GridLength(100, GridUnitType.Pixel)),
new TextColumn<Model, string?>("Title1", x => x.Title, width: new GridLength(100, GridUnitType.Pixel)),
]);
var scroll = Assert.IsType<ScrollViewer>(target.Scroll);
var headerScroll = Assert.IsType<ScrollViewer>(
target.GetVisualDescendants().Single(x => x.Name == "PART_HeaderScrollViewer"));

Assert.Equal(new(100, 100), scroll.Viewport);
Assert.Equal(new(200, 1000), scroll.Extent);
Assert.Equal(new(100, 0), headerScroll.Viewport);
Assert.Equal(new(200, 0), headerScroll.Extent);
}

[AvaloniaFact(Timeout = 10000)]
public void Should_Show_Horizontal_ScrollBar_With_No_Initial_Rows()
{
var (target, items) = CreateTarget(columns:
[
new TextColumn<Model, int>("ID", x => x.Id, width: new GridLength(100, GridUnitType.Pixel)),
new TextColumn<Model, string?>("Title1", x => x.Title, width: new GridLength(100, GridUnitType.Pixel)),
], itemCount: 0);
var scroll = Assert.IsType<ScrollViewer>(target.Scroll);
var headerScroll = Assert.IsType<ScrollViewer>(
target.GetVisualDescendants().Single(x => x.Name == "PART_HeaderScrollViewer"));

Assert.Equal(new(100, 100), scroll.Viewport);
Assert.Equal(new(200, 100), scroll.Extent);
Assert.Equal(new(100, 0), headerScroll.Viewport);
Assert.Equal(new(200, 0), headerScroll.Extent);
}

[AvaloniaFact(Timeout = 10000)]
public void Should_Preserve_Horizontal_ScrollBar_When_Rows_Removed()
{
var (target, items) = CreateTarget(columns:
[
new TextColumn<Model, int>("ID", x => x.Id, width: new GridLength(100, GridUnitType.Pixel)),
new TextColumn<Model, string?>("Title1", x => x.Title, width: new GridLength(100, GridUnitType.Pixel)),
]);
var scroll = Assert.IsType<ScrollViewer>(target.Scroll);
var headerScroll = Assert.IsType<ScrollViewer>(
target.GetVisualDescendants().Single(x => x.Name == "PART_HeaderScrollViewer"));

scroll.PropertyChanged += (s, e) =>
{
if (e.Property == ScrollViewer.ExtentProperty)
{
}
};
items.Clear();
target.UpdateLayout();

Assert.Equal(new(100, 100), scroll.Viewport);
Assert.Equal(new(200, 100), scroll.Extent);
Assert.Equal(new(100, 0), headerScroll.Viewport);
Assert.Equal(new(200, 0), headerScroll.Extent);
}

private static void AssertRowIndexes(TreeDataGrid target, int firstRowIndex, int rowCount)
{
var presenter = target.RowsPresenter;
Expand Down

0 comments on commit 1cd818d

Please sign in to comment.