PageStack.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System.Collections.ObjectModel;
  2. using System.Collections.Specialized;
  3. using Avalonia;
  4. using Avalonia.Controls;
  5. using Avalonia.Controls.Primitives;
  6. using Avalonia.Metadata;
  7. using Avalonia.Threading;
  8. namespace InABox.Avalonia.Components;
  9. public class PageStack : ContentControl
  10. {
  11. private static readonly StyledProperty<PageStackItem?> SelectedItemProperty =
  12. AvaloniaProperty.Register<PageStack,PageStackItem?>(nameof(SelectedItem));
  13. private static readonly StyledProperty<int> SelectedIndexProperty =
  14. AvaloniaProperty.Register<PageStack, int>(nameof(SelectedIndex), -1);
  15. static PageStack()
  16. {
  17. SelectedIndexProperty.Changed.AddClassHandler<PageStack>((stack,args) =>
  18. stack?.SelectPage((int)(args.NewValue ?? -1)));
  19. SelectedItemProperty.Changed.AddClassHandler<PageStack>((stack,args) =>
  20. stack?.SelectPage(args.NewValue as PageStackItem));
  21. }
  22. public PageStack()
  23. {
  24. var items = new ObservableCollection<PageStackItem>();
  25. items.CollectionChanged += ItemsChanged;
  26. Items = items;
  27. }
  28. [Content]
  29. public IList<PageStackItem> Items { get; private set; }
  30. public void SelectPage(int page)
  31. {
  32. SelectPage((page > -1) && (page < Items.Count) ? Items[page] : null);
  33. }
  34. private PageStackItem? _current;
  35. public void SelectPage(PageStackItem? page)
  36. {
  37. if (_current != null)
  38. _current.DoDisappearing();
  39. _current = page;
  40. Content = _current?.Content;
  41. _current?.DoAppearing();
  42. SelectionChanged?.Invoke(this, EventArgs.Empty);
  43. }
  44. public int SelectedIndex
  45. {
  46. get => GetValue(SelectedIndexProperty);
  47. set => SetValue(SelectedIndexProperty, value);
  48. }
  49. public PageStackItem? SelectedItem
  50. {
  51. get => GetValue(SelectedItemProperty);
  52. set => SetValue(SelectedItemProperty, value);
  53. }
  54. public event EventHandler SelectionChanged;
  55. public void DoSelectionChanged()
  56. {
  57. SelectionChanged?.Invoke(this, EventArgs.Empty);
  58. }
  59. private void ItemsChanged(object? sender, NotifyCollectionChangedEventArgs? e)
  60. {
  61. Dispatcher.UIThread.Post(() =>
  62. {
  63. SelectedItem ??= Items.FirstOrDefault();
  64. });
  65. }
  66. }