MainView.xaml.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using System.Collections;
  3. using System.Threading.Tasks;
  4. using Avalonia;
  5. using Avalonia.Controls;
  6. using Avalonia.Controls.ApplicationLifetimes;
  7. using Avalonia.LogicalTree;
  8. using Avalonia.Markup.Xaml;
  9. using Avalonia.Media;
  10. using Avalonia.Media.Immutable;
  11. using Avalonia.Platform;
  12. using Avalonia.VisualTree;
  13. using Avalonia.Styling;
  14. using ControlCatalog.Models;
  15. using ControlCatalog.Pages;
  16. using ControlCatalog.ViewModels;
  17. namespace ControlCatalog
  18. {
  19. public class MainView : UserControl
  20. {
  21. public MainView()
  22. {
  23. AvaloniaXamlLoader.Load(this);
  24. var sideBar = this.Get<TabControl>("Sidebar");
  25. var themes = this.Get<ComboBox>("Themes");
  26. themes.SelectedItem = App.CurrentTheme;
  27. themes.SelectionChanged += (sender, e) =>
  28. {
  29. if (themes.SelectedItem is CatalogTheme theme)
  30. {
  31. App.SetCatalogThemes(theme);
  32. }
  33. };
  34. var themeVariants = this.Get<ComboBox>("ThemeVariants");
  35. themeVariants.SelectedItem = Application.Current!.RequestedThemeVariant;
  36. themeVariants.SelectionChanged += (sender, e) =>
  37. {
  38. if (themeVariants.SelectedItem is ThemeVariant themeVariant)
  39. {
  40. Application.Current!.RequestedThemeVariant = themeVariant;
  41. }
  42. };
  43. var flowDirections = this.Get<ComboBox>("FlowDirection");
  44. flowDirections.SelectionChanged += (sender, e) =>
  45. {
  46. if (flowDirections.SelectedItem is FlowDirection flowDirection)
  47. {
  48. TopLevel.GetTopLevel(this)!.FlowDirection = flowDirection;
  49. }
  50. };
  51. var decorations = this.Get<ComboBox>("Decorations");
  52. decorations.SelectionChanged += (sender, e) =>
  53. {
  54. if (VisualRoot is Window window
  55. && decorations.SelectedItem is SystemDecorations systemDecorations)
  56. {
  57. window.SystemDecorations = systemDecorations;
  58. }
  59. };
  60. var transparencyLevels = this.Get<ComboBox>("TransparencyLevels");
  61. IDisposable? topLevelBackgroundSideSetter = null, sideBarBackgroundSetter = null, paneBackgroundSetter = null;
  62. transparencyLevels.SelectionChanged += (sender, e) =>
  63. {
  64. topLevelBackgroundSideSetter?.Dispose();
  65. sideBarBackgroundSetter?.Dispose();
  66. paneBackgroundSetter?.Dispose();
  67. if (transparencyLevels.SelectedItem is WindowTransparencyLevel selected)
  68. {
  69. var topLevel = (TopLevel)this.GetVisualRoot()!;
  70. topLevel.TransparencyLevelHint = new[] { selected };
  71. if (topLevel.ActualTransparencyLevel != WindowTransparencyLevel.None &&
  72. topLevel.ActualTransparencyLevel == selected)
  73. {
  74. var transparentBrush = new ImmutableSolidColorBrush(Colors.White, 0);
  75. var semiTransparentBrush = new ImmutableSolidColorBrush(Colors.Gray, 0.2);
  76. topLevelBackgroundSideSetter = topLevel.SetValue(BackgroundProperty, transparentBrush, Avalonia.Data.BindingPriority.Style);
  77. sideBarBackgroundSetter = sideBar.SetValue(BackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
  78. paneBackgroundSetter = sideBar.SetValue(SplitView.PaneBackgroundProperty, semiTransparentBrush, Avalonia.Data.BindingPriority.Style);
  79. }
  80. }
  81. };
  82. }
  83. internal MainWindowViewModel ViewModel => (MainWindowViewModel)DataContext!;
  84. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
  85. {
  86. base.OnAttachedToVisualTree(e);
  87. var decorations = this.Get<ComboBox>("Decorations");
  88. if (VisualRoot is Window window)
  89. decorations.SelectedIndex = (int)window.SystemDecorations;
  90. var insets = TopLevel.GetTopLevel(this)!.InsetsManager;
  91. if (insets != null)
  92. {
  93. // In real life application these events should be unsubscribed to avoid memory leaks.
  94. ViewModel.SafeAreaPadding = insets.SafeAreaPadding;
  95. insets.SafeAreaChanged += (sender, args) =>
  96. {
  97. ViewModel.SafeAreaPadding = insets.SafeAreaPadding;
  98. };
  99. ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdgePreference;
  100. ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
  101. ViewModel.PropertyChanged += async (sender, args) =>
  102. {
  103. if (args.PropertyName == nameof(ViewModel.DisplayEdgeToEdge))
  104. {
  105. insets.DisplayEdgeToEdgePreference = ViewModel.DisplayEdgeToEdge;
  106. }
  107. else if (args.PropertyName == nameof(ViewModel.IsSystemBarVisible))
  108. {
  109. insets.IsSystemBarVisible = ViewModel.IsSystemBarVisible;
  110. }
  111. // Give the OS some time to apply new values and refresh the view model.
  112. await Task.Delay(100);
  113. ViewModel.DisplayEdgeToEdge = insets.DisplayEdgeToEdgePreference;
  114. ViewModel.IsSystemBarVisible = insets.IsSystemBarVisible ?? true;
  115. };
  116. }
  117. }
  118. }
  119. }