Browse Source

Added Carousel.IsVirtualized.

pull/508/head
Steven Kirk 10 years ago
parent
commit
a2ea7e36e3
  1. 18
      src/Perspex.Controls/Carousel.cs
  2. 2
      src/Perspex.Controls/Generators/ItemContainerGenerator.cs
  3. 44
      src/Perspex.Controls/Presenters/CarouselPresenter.cs
  4. 3
      src/Perspex.Themes.Default/Carousel.xaml
  5. 45
      tests/Perspex.Controls.UnitTests/CarouselTests.cs
  6. 38
      tests/Perspex.Controls.UnitTests/Presenters/CarouselPresenterTests.cs

18
src/Perspex.Controls/Carousel.cs

@ -14,6 +14,12 @@ namespace Perspex.Controls
/// </summary>
public class Carousel : SelectingItemsControl
{
/// <summary>
/// Defines the <see cref="IsVirtualized"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsVirtualizedProperty =
PerspexProperty.Register<Carousel, bool>(nameof(IsVirtualized), true);
/// <summary>
/// Defines the <see cref="Transition"/> property.
/// </summary>
@ -35,6 +41,18 @@ namespace Perspex.Controls
SelectionModeProperty.OverrideDefaultValue<Carousel>(SelectionMode.AlwaysSelected);
ItemsPanelProperty.OverrideDefaultValue<Carousel>(PanelTemplate);
}
/// <summary>
/// Gets or sets a value indicating whether the items in the carousel are virtualized.
/// </summary>
/// <remarks>
/// When the carousel is virtualized, only the active page is held in memory.
/// </remarks>
public bool IsVirtualized
{
get { return GetValue(IsVirtualizedProperty); }
set { SetValue(IsVirtualizedProperty, value); }
}
/// <summary>
/// Gets or sets the transition to use when moving between pages.

2
src/Perspex.Controls/Generators/ItemContainerGenerator.cs

@ -29,7 +29,7 @@ namespace Perspex.Controls.Generators
}
/// <inheritdoc/>
public IEnumerable<ItemContainer> Containers => _containers;
public IEnumerable<ItemContainer> Containers => _containers.Where(x => x != null);
/// <inheritdoc/>
public event EventHandler<ItemContainerEventArgs> Materialized;

44
src/Perspex.Controls/Presenters/CarouselPresenter.cs

@ -20,6 +20,12 @@ namespace Perspex.Controls.Presenters
/// </summary>
public class CarouselPresenter : Control, IItemsPresenter
{
/// <summary>
/// Defines the <see cref="IsVirtualized"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsVirtualizedProperty =
Carousel.IsVirtualizedProperty.AddOwner<CarouselPresenter>();
/// <summary>
/// Defines the <see cref="Items"/> property.
/// </summary>
@ -96,6 +102,18 @@ namespace Perspex.Controls.Presenters
}
}
/// <summary>
/// Gets or sets a value indicating whether the items in the carousel are virtualized.
/// </summary>
/// <remarks>
/// When the carousel is virtualized, only the active page is held in memory.
/// </remarks>
public bool IsVirtualized
{
get { return GetValue(IsVirtualizedProperty); }
set { SetValue(IsVirtualizedProperty, value); }
}
/// <summary>
/// Gets or sets the items to display.
/// </summary>
@ -212,13 +230,17 @@ namespace Perspex.Controls.Presenters
if (toIndex != -1)
{
var item = Items.Cast<object>().ElementAt(toIndex);
to = generator.ContainerFromIndex(toIndex) ??
generator.Materialize(toIndex, new[] { item }, MemberSelector)
.FirstOrDefault()?.ContainerControl;
to = generator.ContainerFromIndex(toIndex);
if (to != null)
if (to == null)
{
Panel.Children.Add(to);
to = generator.Materialize(toIndex, new[] { item }, MemberSelector)
.FirstOrDefault()?.ContainerControl;
if (to != null)
{
Panel.Children.Add(to);
}
}
}
@ -233,10 +255,16 @@ namespace Perspex.Controls.Presenters
if (from != null)
{
Panel.Children.Remove(from);
generator.Dematerialize(fromIndex, 1);
if (IsVirtualized)
{
Panel.Children.Remove(from);
generator.Dematerialize(fromIndex, 1);
}
else
{
from.IsVisible = false;
}
}
}
}

3
src/Perspex.Themes.Default/Carousel.xaml

@ -4,7 +4,8 @@
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<CarouselPresenter Items="{TemplateBinding Items}"
<CarouselPresenter IsVirtualized="{TemplateBinding IsVirtualized}"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
Margin="{TemplateBinding Padding}"
MemberSelector="{TemplateBinding MemberSelector}"

45
tests/Perspex.Controls.UnitTests/CarouselTests.cs

@ -54,14 +54,53 @@ namespace Perspex.Controls.UnitTests
Assert.Equal("Foo", ((TextBlock)child).Text);
}
[Fact]
public void Should_Remove_NonCurrent_Page_When_IsVirtualized_True()
{
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = new[] { "foo", "bar" },
IsVirtualized = true,
SelectedIndex = 0,
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
target.SelectedIndex = 1;
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
}
[Fact]
public void Should_Not_Remove_NonCurrent_Page_When_IsVirtualized_False()
{
var target = new Carousel
{
Template = new FuncControlTemplate<Carousel>(CreateTemplate),
Items = new[] { "foo", "bar" },
IsVirtualized = false,
SelectedIndex = 0,
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
target.SelectedIndex = 1;
Assert.Equal(2, target.ItemContainerGenerator.Containers.Count());
}
private Control CreateTemplate(Carousel control)
{
return new CarouselPresenter
{
Name = "PART_ItemsPresenter",
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~CarouselPresenter.SelectedIndexProperty] = control[~SelectingItemsControl.SelectedIndexProperty],
[~CarouselPresenter.IsVirtualizedProperty] = control[~Carousel.IsVirtualizedProperty],
[~CarouselPresenter.ItemsProperty] = control[~Carousel.ItemsProperty],
[~CarouselPresenter.ItemsPanelProperty] = control[~Carousel.ItemsPanelProperty],
[~CarouselPresenter.SelectedIndexProperty] = control[~Carousel.SelectedIndexProperty],
[~CarouselPresenter.TransitionProperty] = control[~Carousel.TransitionProperty],
};
}

38
tests/Perspex.Controls.UnitTests/Presenters/CarouselPresenterTests.cs

@ -1,6 +1,7 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Linq;
using Moq;
using Perspex.Controls.Generators;
using Perspex.Controls.Presenters;
@ -78,6 +79,43 @@ namespace Perspex.Controls.UnitTests.Presenters
Assert.Equal("bar", ((TextBlock)target.Panel.Children[0]).Text);
}
[Fact]
public void Should_Remove_NonCurrent_Page_When_IsVirtualized_True()
{
var target = new CarouselPresenter
{
Items = new[] { "foo", "bar" },
IsVirtualized = true,
SelectedIndex = 0,
};
target.ApplyTemplate();
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
target.SelectedIndex = 1;
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
}
[Fact]
public void Should_Not_Remove_NonCurrent_Page_When_IsVirtualized_False()
{
var target = new CarouselPresenter
{
Items = new[] { "foo", "bar" },
IsVirtualized = false,
SelectedIndex = 0,
};
target.ApplyTemplate();
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
Assert.Equal(1, target.Panel.Children.Count);
target.SelectedIndex = 1;
Assert.Equal(2, target.ItemContainerGenerator.Containers.Count());
Assert.Equal(2, target.Panel.Children.Count);
target.SelectedIndex = 0;
Assert.Equal(2, target.ItemContainerGenerator.Containers.Count());
Assert.Equal(2, target.Panel.Children.Count);
}
private class TestItem : ContentControl
{
}

Loading…
Cancel
Save