Browse Source

Allow TransitioningContentControl to be reversed. (#13003)

* Allow TransitioningContentControl to be reversed. (#12442)

* Fix incorrect property name.

* Add missing pseudoclass attribute.

* Remove reversed transition pseudo class as discussed in review.

* Update samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs

Co-authored-by: Max Katz <maxkatz6@outlook.com>

---------

Co-authored-by: Max Katz <maxkatz6@outlook.com>
release/11.0.8
Alshain 2 years ago
committed by Max Katz
parent
commit
cf8b072c5c
  1. 3
      samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml
  2. 12
      samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs
  3. 20
      src/Avalonia.Controls/TransitioningContentControl.cs
  4. 31
      tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs

3
samples/ControlCatalog/Pages/TransitioningContentControlPage.axaml

@ -69,7 +69,8 @@
<Border ClipToBounds="{Binding ClipToBounds}" Margin="5">
<TransitioningContentControl Content="{Binding SelectedImage}"
PageTransition="{Binding SelectedTransition.Transition}" >
PageTransition="{Binding SelectedTransition.Transition}"
IsTransitionReversed="{Binding Reversed}">
<TransitioningContentControl.ContentTemplate>
<DataTemplate DataType="Bitmap">
<Image Source="{Binding}" />

12
samples/ControlCatalog/ViewModels/TransitioningContentControlPageViewModel.cs

@ -46,6 +46,7 @@ namespace ControlCatalog.ViewModels
private Bitmap _SelectedImage;
private bool _Reversed;
/// <summary>
/// Gets or Sets the selected image
@ -97,6 +98,15 @@ namespace ControlCatalog.ViewModels
}
}
/// <summary>
/// Gets or sets a value indicating whether the animation is reversed.
/// </summary>
public bool Reversed
{
get => _Reversed;
set => this.RaiseAndSetIfChanged(ref _Reversed, value);
}
private void SetupTransitions()
{
if (PageTransitions.Count == 0)
@ -127,6 +137,7 @@ namespace ControlCatalog.ViewModels
public void NextImage()
{
Reversed = false;
var index = Images.IndexOf(SelectedImage) + 1;
if (index >= Images.Count)
@ -139,6 +150,7 @@ namespace ControlCatalog.ViewModels
public void PrevImage()
{
Reversed = true;
var index = Images.IndexOf(SelectedImage) - 1;
if (index < 0)

20
src/Avalonia.Controls/TransitioningContentControl.cs

@ -28,6 +28,14 @@ public class TransitioningContentControl : ContentControl
nameof(PageTransition),
defaultValue: new ImmutableCrossFade(TimeSpan.FromMilliseconds(125)));
/// <summary>
/// Defines the <see cref="IsTransitionReversed"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsTransitionReversedProperty =
AvaloniaProperty.Register<TransitioningContentControl, bool>(
nameof(IsTransitionReversed),
defaultValue: false);
/// <summary>
/// Gets or sets the animation played when content appears and disappears.
/// </summary>
@ -37,6 +45,16 @@ public class TransitioningContentControl : ContentControl
set => SetValue(PageTransitionProperty, value);
}
/// <summary>
/// Gets or sets a value indicating whether the control will be animated in the reverse direction.
/// </summary>
/// <remarks>May not apply to all transitions.</remarks>
public bool IsTransitionReversed
{
get => GetValue(IsTransitionReversedProperty);
set => SetValue(IsTransitionReversedProperty, value);
}
protected override Size ArrangeOverride(Size finalSize)
{
var result = base.ArrangeOverride(finalSize);
@ -57,7 +75,7 @@ public class TransitioningContentControl : ContentControl
var from = _isFirstFull ? _presenter2 : presenter;
var to = _isFirstFull ? presenter : _presenter2;
transition.Start(from, to, true, cancel.Token).ContinueWith(x =>
transition.Start(from, to, !IsTransitionReversed, cancel.Token).ContinueWith(x =>
{
if (!cancel.IsCancellationRequested)
{

31
tests/Avalonia.Controls.UnitTests/TransitioningContentControlTests.cs

@ -183,6 +183,37 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal("bar", presenter2.Content);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Transition_Should_Be_Reversed_If_Property_Is_Set(bool reversed)
{
using var app = Start();
using var sync = UnitTestSynchronizationContext.Begin();
var (target, transition) = CreateTarget("foo");
var presenter2 = GetContentPresenters2(target);
target.IsTransitionReversed = reversed;
target.Content = "bar";
var startedRaised = 0;
transition.Started += (from, to, forward) =>
{
Assert.Equal(reversed, !forward);
++startedRaised;
};
Layout(target);
sync.ExecutePostedCallbacks();
Assert.Equal(1, startedRaised);
Assert.Equal("foo", target.Presenter!.Content);
Assert.Equal("bar", presenter2.Content);
}
[Fact]
public void Logical_Children_Should_Not_Be_Duplicated()
{

Loading…
Cancel
Save