NavigationPageInteractiveHeaderPage.xaml.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.Templates;
  5. using Avalonia.Interactivity;
  6. using Avalonia.Layout;
  7. using Avalonia.Media;
  8. namespace ControlCatalog.Pages
  9. {
  10. public record ContactItem(string Name, string Role);
  11. public partial class NavigationPageInteractiveHeaderPage : UserControl
  12. {
  13. private static readonly ContactItem[] AllContacts =
  14. [
  15. new("Alice Martin", "Engineering Lead"),
  16. new("Bob Chen", "Product Designer"),
  17. new("Carol White", "Frontend Developer"),
  18. new("David Kim", "Backend Developer"),
  19. new("Eva Müller", "UX Researcher"),
  20. new("Frank Lopez", "QA Engineer"),
  21. new("Grace Zhang", "Data Scientist"),
  22. new("Henry Brown", "DevOps Engineer"),
  23. new("Iris Patel", "Security Analyst"),
  24. new("Jack Robinson", "Mobile Developer"),
  25. new("Karen Lee", "Project Manager"),
  26. new("Liam Thompson", "Full-Stack Developer"),
  27. new("Maya Singh", "Backend Developer"),
  28. new("Noah Garcia", "iOS Developer"),
  29. new("Olivia Davis", "Android Developer"),
  30. new("Paul Wilson", "Systems Architect"),
  31. new("Quinn Adams", "Technical Writer"),
  32. new("Rachel Turner", "Data Engineer"),
  33. new("Samuel Hall", "Cloud Engineer"),
  34. new("Tina Scott", "UI Designer"),
  35. ];
  36. private readonly ObservableCollection<ContactItem> _filteredItems = new(AllContacts);
  37. private bool _initialized;
  38. private string _searchText = "";
  39. public NavigationPageInteractiveHeaderPage()
  40. {
  41. InitializeComponent();
  42. Loaded += OnLoaded;
  43. }
  44. private async void OnLoaded(object? sender, RoutedEventArgs e)
  45. {
  46. if (_initialized)
  47. return;
  48. _initialized = true;
  49. var headerGrid = new Grid
  50. {
  51. ColumnDefinitions = new ColumnDefinitions("*, Auto"),
  52. VerticalAlignment = VerticalAlignment.Stretch,
  53. };
  54. var titleBlock = new TextBlock
  55. {
  56. Text = "Contacts",
  57. FontSize = 16,
  58. FontWeight = FontWeight.SemiBold,
  59. VerticalAlignment = VerticalAlignment.Center,
  60. };
  61. Grid.SetColumn(titleBlock, 0);
  62. var searchBox = new TextBox
  63. {
  64. PlaceholderText = "Search...",
  65. Width = 140,
  66. VerticalAlignment = VerticalAlignment.Center,
  67. };
  68. Grid.SetColumn(searchBox, 1);
  69. searchBox.TextChanged += (_, _) =>
  70. {
  71. _searchText = searchBox.Text ?? "";
  72. ApplyFilter();
  73. };
  74. headerGrid.Children.Add(titleBlock);
  75. headerGrid.Children.Add(searchBox);
  76. var resultLabel = new TextBlock
  77. {
  78. Text = $"{AllContacts.Length} contacts",
  79. FontSize = 12,
  80. Opacity = 0.6,
  81. Margin = new Avalonia.Thickness(16, 8),
  82. };
  83. var listBox = new ListBox
  84. {
  85. ItemsSource = _filteredItems,
  86. ItemTemplate = new FuncDataTemplate<ContactItem>((item, _) =>
  87. {
  88. if (item == null)
  89. return new TextBlock();
  90. var panel = new StackPanel { Margin = new Avalonia.Thickness(4, 2) };
  91. panel.Children.Add(new TextBlock
  92. {
  93. Text = item.Name,
  94. FontSize = 14,
  95. FontWeight = FontWeight.SemiBold,
  96. });
  97. panel.Children.Add(new TextBlock
  98. {
  99. Text = item.Role,
  100. FontSize = 12,
  101. Opacity = 0.6,
  102. });
  103. return panel;
  104. }),
  105. };
  106. _filteredItems.CollectionChanged += (_, _) =>
  107. {
  108. resultLabel.Text = string.IsNullOrWhiteSpace(_searchText)
  109. ? $"{AllContacts.Length} contacts"
  110. : $"{_filteredItems.Count} of {AllContacts.Length} contacts";
  111. };
  112. var content = new DockPanel();
  113. DockPanel.SetDock(resultLabel, Dock.Top);
  114. content.Children.Add(resultLabel);
  115. content.Children.Add(listBox);
  116. await DemoNav.PushAsync(new ContentPage
  117. {
  118. Header = headerGrid,
  119. Content = content,
  120. HorizontalContentAlignment = HorizontalAlignment.Stretch,
  121. VerticalContentAlignment = VerticalAlignment.Stretch,
  122. }, null);
  123. }
  124. private void ApplyFilter()
  125. {
  126. _filteredItems.Clear();
  127. foreach (var c in AllContacts)
  128. {
  129. if (string.IsNullOrEmpty(_searchText) ||
  130. c.Name.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ||
  131. c.Role.Contains(_searchText, StringComparison.OrdinalIgnoreCase))
  132. {
  133. _filteredItems.Add(c);
  134. }
  135. }
  136. }
  137. }
  138. }