using Avalonia.Animation; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; namespace Avalonia.Controls { /// /// An items control that displays its items as pages that fill the control. /// public class Carousel : SelectingItemsControl { /// /// Defines the property. /// public static readonly StyledProperty PageTransitionProperty = AvaloniaProperty.Register(nameof(PageTransition)); /// /// The default value of for /// . /// private static readonly FuncTemplate DefaultPanel = new(() => new VirtualizingCarouselPanel()); private IScrollable? _scroller; /// /// Initializes static members of the class. /// static Carousel() { SelectionModeProperty.OverrideDefaultValue(SelectionMode.AlwaysSelected); ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); } /// /// Gets or sets the transition to use when moving between pages. /// public IPageTransition? PageTransition { get { return GetValue(PageTransitionProperty); } set { SetValue(PageTransitionProperty, value); } } /// /// Moves to the next item in the carousel. /// public void Next() { if (SelectedIndex < ItemCount - 1) { ++SelectedIndex; } } /// /// Moves to the previous item in the carousel. /// public void Previous() { if (SelectedIndex > 0) { --SelectedIndex; } } protected override Size ArrangeOverride(Size finalSize) { var result = base.ArrangeOverride(finalSize); if (_scroller is not null) _scroller.Offset = new(SelectedIndex, 0); return result; } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); _scroller = e.NameScope.Find("PART_ScrollViewer"); } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); if (change.Property == SelectedIndexProperty && _scroller is not null) { var value = change.GetNewValue(); _scroller.Offset = new(value, 0); } } } }