Browse Source

Fix selection after deleting an item.

`SelectionModel` needs to subscribe to `CollectionChanged` on the items before `ItemsControl` in order for the selection to be correct when we come to setting the selected state.

Because `SelectionModel.Source` isn't subscribed during initialization in `ItemsChanged`, we also need to make sure we don't subscribe `ItemsControl` to the collection changes during initialization. Instead subscribe in `OnInitialized` (this requires a few tests to be rooted in order to be called).

Fixes #4293
pull/4294/head
Steven Kirk 6 years ago
parent
commit
6555a51f5a
  1. 11
      src/Avalonia.Controls/ItemsControl.cs
  2. 3
      tests/Avalonia.Controls.UnitTests/CarouselTests.cs
  3. 4
      tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs
  4. 4
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
  5. 4
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

11
src/Avalonia.Controls/ItemsControl.cs

@ -70,7 +70,6 @@ namespace Avalonia.Controls
public ItemsControl()
{
PseudoClasses.Add(":empty");
SubscribeToItems(_items);
}
/// <summary>
@ -265,6 +264,11 @@ namespace Avalonia.Controls
{
}
protected override void OnInitialized()
{
SubscribeToItems(_items);
}
/// <summary>
/// Handles directional navigation within the <see cref="ItemsControl"/>.
/// </summary>
@ -330,7 +334,10 @@ namespace Avalonia.Controls
Presenter.Items = newValue;
}
SubscribeToItems(newValue);
if (IsInitialized)
{
SubscribeToItems(newValue);
}
}
/// <summary>

3
tests/Avalonia.Controls.UnitTests/CarouselTests.cs

@ -4,6 +4,7 @@ using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.LogicalTree;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
@ -155,6 +156,7 @@ namespace Avalonia.Controls.UnitTests
IsVirtualized = false
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
@ -247,6 +249,7 @@ namespace Avalonia.Controls.UnitTests
IsVirtualized = false
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();

4
tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs

@ -131,6 +131,7 @@ namespace Avalonia.Controls.UnitTests
var child = new Control();
var items = new AvaloniaList<Control>(child);
var root = new TestRoot(target);
target.Template = GetTemplate();
target.Items = items;
items.RemoveAt(0);
@ -283,6 +284,7 @@ namespace Avalonia.Controls.UnitTests
var items = new AvaloniaList<string> { "Foo" };
var called = false;
var root = new TestRoot(target);
target.Template = GetTemplate();
target.Items = items;
target.ApplyTemplate();
@ -303,6 +305,7 @@ namespace Avalonia.Controls.UnitTests
var items = new AvaloniaList<string> { "Foo", "Bar" };
var called = false;
var root = new TestRoot(target);
target.Template = GetTemplate();
target.Items = items;
target.ApplyTemplate();
@ -376,6 +379,7 @@ namespace Avalonia.Controls.UnitTests
Items = new[] { 1, 2, 3 },
};
var root = new TestRoot(target);
Assert.DoesNotContain(":empty", target.Classes);
}

4
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@ -170,6 +170,8 @@ namespace Avalonia.Controls.UnitTests.Primitives
SelectionMode = SelectionMode.Single | SelectionMode.AlwaysSelected
};
var root = new TestRoot(listBox);
listBox.BeginInit();
listBox.SelectedIndex = 1;
@ -480,6 +482,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
items.Add(new Item { IsSelected = true });
@ -919,6 +922,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Items = items,
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();

4
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

@ -1014,6 +1014,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
SelectionMode = SelectionMode.Multiple,
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
@ -1043,6 +1044,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
SelectionMode = SelectionMode.Multiple,
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
@ -1076,6 +1078,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
SelectionMode = SelectionMode.Multiple,
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
@ -1199,6 +1202,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
};
var root = new TestRoot(target);
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
items.Add(new ItemContainer { IsSelected = true });

Loading…
Cancel
Save