Skip to content

Commit

Permalink
Merge pull request #303 from AvaloniaUI/fixes/drag-drop-not-updating
Browse files Browse the repository at this point in the history
Handle focused item being removed when outside the viewport.
  • Loading branch information
grokys authored Sep 10, 2024
2 parents 38dce08 + a4bacae commit d183b14
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions samples/TreeDataGridDemo/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class App : Application
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
Bogus.Randomizer.Seed = new System.Random(0);
}

public override void OnFrameworkInitializationCompleted()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,13 @@ private void RecycleElement(Control element, int index)

private void RecycleElementOnItemRemoved(Control element)
{
if (element == _focusedElement)
{
_focusedElement.LostFocus -= OnUnrealizedFocusedElementLostFocus;
_focusedElement = null;
_focusedIndex = -1;
}

UnrealizeElementOnItemRemoved(element);
element.IsVisible = false;
ElementFactory!.RecycleElement(element);
Expand Down Expand Up @@ -691,6 +698,12 @@ private void TrimUnrealizedChildren()

private void OnItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
void ClearFocusedElement(int index, int count)
{
if (_focusedElement is not null && _focusedIndex >= index && _focusedIndex < index + count)
RecycleElementOnItemRemoved(_focusedElement);
}

InvalidateMeasure();

if (_realizedElements is null)
Expand All @@ -703,16 +716,21 @@ private void OnItemsCollectionChanged(object? sender, NotifyCollectionChangedEve
break;
case NotifyCollectionChangedAction.Remove:
_realizedElements.ItemsRemoved(e.OldStartingIndex, e.OldItems!.Count, _updateElementIndex, _recycleElementOnItemRemoved);
ClearFocusedElement(e.OldStartingIndex, e.OldItems!.Count);
break;
case NotifyCollectionChangedAction.Replace:
_realizedElements.ItemsReplaced(e.OldStartingIndex, e.OldItems!.Count, _recycleElementOnItemRemoved);
ClearFocusedElement(e.OldStartingIndex, e.OldItems!.Count);
break;
case NotifyCollectionChangedAction.Move:
_realizedElements.ItemsRemoved(e.OldStartingIndex, e.OldItems!.Count, _updateElementIndex, _recycleElementOnItemRemoved);
_realizedElements.ItemsInserted(e.NewStartingIndex, e.NewItems!.Count, _updateElementIndex);
ClearFocusedElement(e.OldStartingIndex, e.OldItems!.Count);
break;
case NotifyCollectionChangedAction.Reset:
_realizedElements.ItemsReset(_recycleElementOnItemRemoved);
if (_focusedElement is not null )
RecycleElementOnItemRemoved(_focusedElement);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,78 @@ public void Handles_Removing_Row_Range_That_Invalidates_Current_Viewport()
Assert.Equal(new Size(100, 100), target.Bounds.Size);
}

[AvaloniaFact(Timeout = 10000)]
public void Handles_Removing_Focused_Row_While_Outside_Viewport()
{
var (target, scroll, items) = CreateTarget();
var element = target.RealizedElements.ElementAt(0)!;

element.Focusable = true;
element.Focus();

// Scroll down one item.
scroll.Offset = new Vector(0, 10);
Layout(target);

// Remove the focused element.
items.RemoveAt(0);

// Scroll back to the beginning.
scroll.Offset = new Vector(0, 0);
Layout(target);

// The correct element should be shown.
Assert.Same(items[0], target.RealizedElements.ElementAt(0)!.DataContext);
}

[AvaloniaFact(Timeout = 10000)]
public void Handles_Replacing_Focused_Row_While_Outside_Viewport()
{
var (target, scroll, items) = CreateTarget();
var element = target.RealizedElements.ElementAt(0)!;

element.Focusable = true;
element.Focus();

// Scroll down one item.
scroll.Offset = new Vector(0, 10);
Layout(target);

// Replace the focused element.
items[0] = new Model { Id = 100, Title = "New Item" };

// Scroll back to the beginning.
scroll.Offset = new Vector(0, 0);
Layout(target);

// The correct element should be shown.
Assert.Same(items[0], target.RealizedElements.ElementAt(0)!.DataContext);
}

[AvaloniaFact(Timeout = 10000)]
public void Handles_Moving_Focused_Row_While_Outside_Viewport()
{
var (target, scroll, items) = CreateTarget();
var element = target.RealizedElements.ElementAt(0)!;

element.Focusable = true;
element.Focus();

// Scroll down one item.
scroll.Offset = new Vector(0, 10);
Layout(target);

// Move the focused element.
items.Move(0, items.Count - 1);

// Scroll back to the beginning.
scroll.Offset = new Vector(0, 0);
Layout(target);

// The correct element should be shown.
Assert.Same(items[0], target.RealizedElements.ElementAt(0)!.DataContext);
}

[AvaloniaFact(Timeout = 10000)]
public void Updates_Star_Column_ActualWidth()
{
Expand Down

0 comments on commit d183b14

Please sign in to comment.