Skip to content

Commit

Permalink
Correctly recycle cells with focus.
Browse files Browse the repository at this point in the history
Previously, a cell with focus wasn't being recycled when the parent row was removed as `TreeDataGridPresenterBase.RecycleElement` was being called on it, which has logic to keep the focused element around. This makes no sense when the containing row has been removed, instead `RecycleElementOnItemRemoved` should be called.

Add `TreeDataGridPresenterBase.UnrealizeOnRowRemoved` (with an override in  `TreeDataGridRowsPresenter`) and make `TreeDataGridPresenterBase.RecycleElementOnItemRemoved` call it.
  • Loading branch information
grokys committed Aug 28, 2023
1 parent 021a1aa commit c19ef94
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ internal void UpdateSelection(ITreeDataGridSelectionInteraction? selection)
}
}

internal void UnrealizeOnRowRemoved()
{
if (RowIndex == -1)
throw new InvalidOperationException("Row is not realized.");
RowIndex = -1;
RecycleAllElementsOnItemRemoved();
}

private ITreeDataGridSelectionInteraction? GetSelection()
{
return this.FindAncestorOfType<TreeDataGrid>()?.SelectionInteraction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ public IEnumerable<Control> GetRealizedElements()

internal void RecycleAllElements() => _realizedElements?.RecycleAllElements(_recycleElement);

internal void RecycleAllElementsOnItemRemoved()
{
_realizedElements?.ItemsRemoved(
_realizedElements.FirstIndex,
_realizedElements.Count,
_updateElementIndex,
_recycleElementOnItemRemoved);
}

protected virtual Rect ArrangeElement(int index, Control element, Rect rect)
{
element.Arrange(rect);
Expand Down Expand Up @@ -427,6 +436,11 @@ protected virtual void OnEffectiveViewportChanged(object? sender, EffectiveViewp
}
}

protected virtual void UnrealizeElementOnItemRemoved(Control element)
{
UnrealizeElement(element);
}

private void RealizeElements(
IReadOnlyList<TItem> items,
Size availableSize,
Expand Down Expand Up @@ -643,7 +657,7 @@ private void RecycleElement(Control element, int index)

private void RecycleElementOnItemRemoved(Control element)
{
UnrealizeElement(element);
UnrealizeElementOnItemRemoved(element);
element.IsVisible = false;
ElementFactory!.RecycleElement(element);
}
Expand Down
11 changes: 10 additions & 1 deletion src/Avalonia.Controls.TreeDataGrid/Primitives/TreeDataGridRow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Text;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Models.TreeDataGrid;
using Avalonia.Controls.Selection;
Expand Down Expand Up @@ -106,7 +107,6 @@ public void Unrealize()
IsSelected = false;
CellsPresenter?.Unrealize();
}

protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
_treeDataGrid = this.FindLogicalAncestorOfType<TreeDataGrid>();
Expand Down Expand Up @@ -177,5 +177,14 @@ internal void UpdateSelection(ITreeDataGridSelectionInteraction? selection)
IsSelected = selection?.IsRowSelected(RowIndex) ?? false;
CellsPresenter?.UpdateSelection(selection);
}

public void UnrealizeOnItemRemoved()
{
_treeDataGrid?.RaiseRowClearing(this, RowIndex);
RowIndex = -1;
DataContext = null;
IsSelected = false;
CellsPresenter?.UnrealizeOnRowRemoved();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ protected override void UnrealizeElement(Control element)
ChildIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(element, ((TreeDataGridRow)element).RowIndex));
}

protected override void UnrealizeElementOnItemRemoved(Control element)
{
((TreeDataGridRow)element).UnrealizeOnItemRemoved();
ChildIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(element, ((TreeDataGridRow)element).RowIndex));
}

protected override Size ArrangeOverride(Size finalSize)
{
Columns?.CommitActualWidths();
Expand Down

0 comments on commit c19ef94

Please sign in to comment.