CommandBarPage.xaml.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using System;
  2. using System.Collections.Generic;
  3. using Avalonia.Controls;
  4. using Avalonia.Interactivity;
  5. using Avalonia.Layout;
  6. using Avalonia.Media;
  7. namespace ControlCatalog.Pages
  8. {
  9. public partial class CommandBarPage : ContentPage
  10. {
  11. private static readonly (string Group, string Title, string Description, Func<UserControl> Factory)[] Demos =
  12. {
  13. // Overview
  14. ("Overview", "First Look", "A CommandBar with primary commands, secondary overflow menu, and custom content area.", () => new CommandBarFirstLookPage()),
  15. ("Overview", "Toggle Buttons", "CommandBarToggleButton for stateful actions like Bold, Italic, and Favorite.", () => new CommandBarTogglePage()),
  16. // Appearance
  17. ("Appearance", "Label Positions", "Configure label position: Bottom (default), Right, or Collapsed (icon only).", () => new CommandBarLabelPositionPage()),
  18. ("Appearance", "Customization", "Background, Foreground, BorderBrush, BorderThickness, and CornerRadius.", () => new CommandBarCustomizationPage()),
  19. // Features
  20. ("Features", "Overflow Menu", "Secondary commands appear in an overflow popup. Configure visibility and sticky behavior.", () => new CommandBarOverflowPage()),
  21. ("Features", "Dynamic Overflow", "IsDynamicOverflowEnabled moves primary commands to overflow as space shrinks.", () => new CommandBarDynamicOverflowPage()),
  22. ("Features", "Events & State", "Observe Opening, Opened, Closing, and Closed while tracking IsOpen, HasSecondaryCommands, and IsOverflowButtonVisible.", () => new CommandBarEventsPage()),
  23. ("Features", "Keyboard Navigation", "Up/Down to move between overflow items, Home/End to jump to first/last, Escape to close and return focus.", () => new CommandBarKeyboardPage()),
  24. };
  25. public CommandBarPage()
  26. {
  27. InitializeComponent();
  28. Loaded += OnLoaded;
  29. }
  30. private async void OnLoaded(object? sender, RoutedEventArgs e)
  31. {
  32. await SampleNav.PushAsync(CreateHomePage(), null);
  33. }
  34. private ContentPage CreateHomePage()
  35. {
  36. var stack = new StackPanel
  37. {
  38. Margin = new Avalonia.Thickness(12),
  39. Spacing = 16
  40. };
  41. var groups = new Dictionary<string, WrapPanel>();
  42. var groupOrder = new List<string>();
  43. foreach (var (group, title, description, factory) in Demos)
  44. {
  45. if (!groups.ContainsKey(group))
  46. {
  47. groups[group] = new WrapPanel
  48. {
  49. Orientation = Orientation.Horizontal,
  50. HorizontalAlignment = HorizontalAlignment.Left
  51. };
  52. groupOrder.Add(group);
  53. }
  54. var demoFactory = factory;
  55. var demoTitle = title;
  56. var card = new Button
  57. {
  58. Width = 170,
  59. MinHeight = 80,
  60. Margin = new Avalonia.Thickness(0, 0, 8, 8),
  61. VerticalAlignment = VerticalAlignment.Top,
  62. HorizontalContentAlignment = HorizontalAlignment.Left,
  63. VerticalContentAlignment = VerticalAlignment.Top,
  64. Padding = new Avalonia.Thickness(12, 8),
  65. Content = new StackPanel
  66. {
  67. Spacing = 4,
  68. Children =
  69. {
  70. new TextBlock
  71. {
  72. Text = title,
  73. FontSize = 13,
  74. FontWeight = FontWeight.SemiBold,
  75. TextWrapping = TextWrapping.Wrap
  76. },
  77. new TextBlock
  78. {
  79. Text = description,
  80. FontSize = 11,
  81. Opacity = 0.6,
  82. TextWrapping = TextWrapping.Wrap
  83. }
  84. }
  85. }
  86. };
  87. card.Click += async (s, e) =>
  88. {
  89. var headerGrid = new Grid { ColumnDefinitions = new ColumnDefinitions("*, Auto") };
  90. headerGrid.Children.Add(new TextBlock
  91. {
  92. Text = demoTitle,
  93. VerticalAlignment = VerticalAlignment.Center
  94. });
  95. var closeBtn = new Button
  96. {
  97. Content = new PathIcon
  98. {
  99. Data = Geometry.Parse("M4.397 4.397a1 1 0 0 1 1.414 0L12 10.585l6.19-6.188a1 1 0 0 1 1.414 1.414L13.413 12l6.19 6.189a1 1 0 0 1-1.414 1.414L12 13.413l-6.189 6.19a1 1 0 0 1-1.414-1.414L10.585 12 4.397 5.811a1 1 0 0 1 0-1.414z")
  100. },
  101. Background = Brushes.Transparent,
  102. BorderThickness = new Avalonia.Thickness(0),
  103. Padding = new Avalonia.Thickness(8, 4),
  104. VerticalAlignment = VerticalAlignment.Center
  105. };
  106. Grid.SetColumn(closeBtn, 1);
  107. headerGrid.Children.Add(closeBtn);
  108. closeBtn.Click += async (_, _) => await SampleNav.PopAsync(null);
  109. var page = new ContentPage
  110. {
  111. Header = headerGrid,
  112. Content = demoFactory(),
  113. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  114. VerticalContentAlignment = VerticalAlignment.Stretch
  115. };
  116. NavigationPage.SetHasBackButton(page, false);
  117. await SampleNav.PushAsync(page, null);
  118. };
  119. groups[group].Children.Add(card);
  120. }
  121. foreach (var groupName in groupOrder)
  122. {
  123. stack.Children.Add(new TextBlock
  124. {
  125. Text = groupName,
  126. FontSize = 13,
  127. FontWeight = FontWeight.SemiBold,
  128. Margin = new Avalonia.Thickness(0, 0, 0, 4),
  129. Opacity = 0.6
  130. });
  131. stack.Children.Add(groups[groupName]);
  132. }
  133. var homePage = new ContentPage
  134. {
  135. Content = new ScrollViewer { Content = stack },
  136. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  137. VerticalContentAlignment = VerticalAlignment.Stretch
  138. };
  139. NavigationPage.SetHasNavigationBar(homePage, false);
  140. return homePage;
  141. }
  142. }
  143. }