Browse Source

Merge pull request #1639 from AvaloniaUI/fixes/1569-carousel-collection-changed-handling

Handle all CollectionChanged cases in CarouselPresenter.
pull/1634/merge
danwalmsley 8 years ago
committed by GitHub
parent
commit
6c13dee48d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      src/Avalonia.Controls/Presenters/CarouselPresenter.cs
  2. 171
      tests/Avalonia.Controls.UnitTests/CarouselTests.cs

13
src/Avalonia.Controls/Presenters/CarouselPresenter.cs

@ -106,7 +106,6 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/>
protected override void ItemsChanged(NotifyCollectionChangedEventArgs e)
{
// TODO: Handle items changing.
switch (e.Action)
{
case NotifyCollectionChangedAction.Remove:
@ -115,9 +114,21 @@ namespace Avalonia.Controls.Presenters
var generator = ItemContainerGenerator;
var containers = generator.RemoveRange(e.OldStartingIndex, e.OldItems.Count);
Panel.Children.RemoveAll(containers.Select(x => x.ContainerControl));
MoveToPage(-1, SelectedIndex);
}
break;
case NotifyCollectionChangedAction.Reset:
{
var generator = ItemContainerGenerator;
var containers = generator.Containers.ToList();
generator.Clear();
Panel.Children.RemoveAll(containers.Select(x => x.ContainerControl));
MoveToPage(-1, SelectedIndex >= 0 ? SelectedIndex : 0);
}
break;
}
}

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

@ -1,11 +1,13 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.Controls.UnitTests
@ -50,7 +52,7 @@ namespace Avalonia.Controls.UnitTests
Assert.Single(target.GetLogicalChildren());
var child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Foo", ((TextBlock)child).Text);
}
@ -93,6 +95,173 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(2, target.ItemContainerGenerator.Containers.Count());
}
[Fact]
public void Selected_Item_Changes_To_First_Item_When_Items_Property_Changes()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"FooBar"
};
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = items,
IsVirtualized = false
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Single(target.GetLogicalChildren());
var child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Foo", ((TextBlock)child).Text);
var newItems = items.ToList();
newItems.RemoveAt(0);
target.Items = newItems;
child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Bar", ((TextBlock)child).Text);
}
[Fact]
public void Selected_Item_Changes_To_First_Item_When_Items_Property_Changes_And_Virtualized()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"FooBar"
};
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = items
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Single(target.GetLogicalChildren());
var child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Foo", ((TextBlock)child).Text);
var newItems = items.ToList();
newItems.RemoveAt(0);
target.Items = newItems;
child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Bar", ((TextBlock)child).Text);
}
[Fact]
public void Selected_Index_Is_Maintained_Carousel_Created_With_Non_Zero_SelectedIndex()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"FooBar"
};
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = items,
IsVirtualized = false,
SelectedIndex = 2
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal("FooBar", target.SelectedItem);
var child = target.GetVisualDescendants().LastOrDefault();
Assert.IsType<TextBlock>(child);
Assert.Equal("FooBar", ((TextBlock)child).Text);
}
[Fact]
public void Selected_Item_Changes_To_Next_First_Item_When_Item_Removed_From_Beggining_Of_List()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"FooBar"
};
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = items,
IsVirtualized = false
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Single(target.GetLogicalChildren());
var child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Foo", ((TextBlock)child).Text);
items.RemoveAt(0);
child = target.GetLogicalChildren().Single();
Assert.IsType<TextBlock>(child);
Assert.Equal("Bar", ((TextBlock)child).Text);
}
[Fact]
public void Selected_Item_Changes_To_NextAvailable_Item_If_SelectedItem_Is_Removed_From_Middle()
{
var items = new ObservableCollection<string>
{
"Foo",
"Bar",
"FooBar"
};
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = items,
IsVirtualized = false
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedIndex = 1;
items.RemoveAt(1);
Assert.Equal(1, target.SelectedIndex);
Assert.Equal("FooBar", target.SelectedItem);
}
private Control CreateTemplate(Carousel control)
{
return new CarouselPresenter

Loading…
Cancel
Save