diff --git a/samples/ControlCatalog/Icons.cs b/samples/ControlCatalog/Icons.cs
index 58d0e0b7d4..5f99bdc877 100644
--- a/samples/ControlCatalog/Icons.cs
+++ b/samples/ControlCatalog/Icons.cs
@@ -190,5 +190,8 @@ namespace ControlCatalog
// Slider tune/adjust
public const string Tune = "M3,17V19H9V17H3M3,5V7H13V5H3M13,21V19H21V17H13V15H11V21H13M7,9V11H3V13H7V15H9V9H7M21,13V11H11V13H21M15,9H17V7H21V5H17V3H15V9Z";
+
+ // Home
+ public const string Home = "M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z";
}
}
diff --git a/samples/ControlCatalog/Pages/HomePage.xaml b/samples/ControlCatalog/Pages/HomePage.xaml
new file mode 100644
index 0000000000..bd0d6432fa
--- /dev/null
+++ b/samples/ControlCatalog/Pages/HomePage.xaml
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlCatalog/Pages/HomePage.xaml.cs b/samples/ControlCatalog/Pages/HomePage.xaml.cs
new file mode 100644
index 0000000000..95fa183745
--- /dev/null
+++ b/samples/ControlCatalog/Pages/HomePage.xaml.cs
@@ -0,0 +1,78 @@
+using System;
+using Avalonia;
+using Avalonia.Animation;
+using Avalonia.Controls;
+using Avalonia.Media;
+using Avalonia.Styling;
+using Avalonia.VisualTree;
+using ControlCatalog.ViewModels;
+
+namespace ControlCatalog.Pages
+{
+ public partial class HomePage : ContentPage
+ {
+ public HomePage()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnAttachedToVisualTree(e);
+
+ // Pages hosted in a NavigationPage inherit the navigator as DataContext;
+ // the card grid binds to MainWindowViewModel, so resolve it from MainView.
+ if (DataContext is not MainWindowViewModel)
+ DataContext = this.FindAncestorOfType()?.DataContext;
+
+ StartFloatingAnimation(FloatIcon1, 12, 8, TimeSpan.FromSeconds(12));
+ StartFloatingAnimation(FloatIcon2, -14, 8, TimeSpan.FromSeconds(10));
+ StartFloatingAnimation(FloatIcon3, -12, -12, TimeSpan.FromSeconds(14));
+ StartFloatingAnimation(FloatIcon4, 12, -8, TimeSpan.FromSeconds(11));
+ }
+
+ private static void StartFloatingAnimation(Control target, double dx, double dy, TimeSpan duration)
+ {
+ var transform = new TranslateTransform();
+ target.RenderTransform = transform;
+
+ var animation = new Animation
+ {
+ Duration = duration,
+ IterationCount = IterationCount.Infinite,
+ Children =
+ {
+ new KeyFrame
+ {
+ Cue = new Cue(0d),
+ Setters =
+ {
+ new Setter(TranslateTransform.XProperty, 0d),
+ new Setter(TranslateTransform.YProperty, 0d),
+ }
+ },
+ new KeyFrame
+ {
+ Cue = new Cue(0.5d),
+ Setters =
+ {
+ new Setter(TranslateTransform.XProperty, dx),
+ new Setter(TranslateTransform.YProperty, dy),
+ }
+ },
+ new KeyFrame
+ {
+ Cue = new Cue(1d),
+ Setters =
+ {
+ new Setter(TranslateTransform.XProperty, 0d),
+ new Setter(TranslateTransform.YProperty, 0d),
+ }
+ },
+ }
+ };
+
+ _ = animation.RunAsync(target);
+ }
+ }
+}
diff --git a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
index 0d877b253f..7b9bbac603 100644
--- a/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
+++ b/samples/ControlCatalog/ViewModels/MainWindowViewModel.cs
@@ -37,6 +37,7 @@ namespace ControlCatalog.ViewModels
{
(App.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.Shutdown();
});
+ NavigateToPageCommand = MiniCommand.Create(NavigateToPage);
WindowState = WindowState.Normal;
@@ -127,6 +128,8 @@ namespace ControlCatalog.ViewModels
public MiniCommand ExitCommand { get; }
+ public MiniCommand NavigateToPageCommand { get; }
+
private DateTime? _validatedDateExample;
///
diff --git a/samples/ControlCatalog/ViewModels/MainWindowViewModel_PageList.cs b/samples/ControlCatalog/ViewModels/MainWindowViewModel_PageList.cs
index 03047bedae..8142004af8 100644
--- a/samples/ControlCatalog/ViewModels/MainWindowViewModel_PageList.cs
+++ b/samples/ControlCatalog/ViewModels/MainWindowViewModel_PageList.cs
@@ -26,78 +26,114 @@ namespace ControlCatalog.ViewModels
private List _items = new()
{
- new PageItem("Composition", () => new CompositionPage(), Icons.Layers),
- new PageItem("Accelerator", () => new AcceleratorPage(), Icons.Keyboard),
- new PageItem("Acrylic", () => new AcrylicPage(), Icons.Blur),
- new PageItem("AdornerLayer", () => new AdornerLayerPage(), Icons.Sparkle),
- new PageItem("AutoCompleteBox",() => new AutoCompleteBoxPage(), Icons.TextInput),
- new PageItem("Border",() => new BorderPage(), Icons.Border),
- new PageItem("BitmapCache",() => new BitmapCachePage(), Icons.Lightning),
- new PageItem("Buttons",() => new ButtonsPage(), Icons.CursorClick),
- new PageItem("ButtonSpinner",() => new ButtonSpinnerPage(), Icons.Spinner),
- new PageItem("Calendar",() => new CalendarPage(), Icons.Calendar),
- new PageItem("Canvas",() => new CanvasPage(), Icons.Canvas),
- new PageItem("CommandBar",() => new CommandBarPage(), Icons.Terminal),
- new PageItem("Carousel",() => new Pages.CarouselPage(), Icons.Slides),
- new PageItem("CarouselPage",() => new CarouselDemoPage(), Icons.Slides),
- new PageItem("CheckBox",() => new CheckBoxPage(), Icons.Checkbox),
- new PageItem("Clipboard",() => new ClipboardPage(), Icons.Clipboard),
- new PageItem("ColorPicker",() => new ColorPickerPage(), Icons.Palette),
- new PageItem("ComboBox",() => new ComboBoxPage(), Icons.Dropdown),
- new PageItem("Container Queries",() => new ContainerQueryPage(), Icons.Container),
- new PageItem("ContentPage",() => new ContentDemoPage(), Icons.Document),
- new PageItem("ContextFlyout",() => new ContextFlyoutPage(), Icons.Menu),
- new PageItem("ContextMenu",() => new ContextMenuPage(), Icons.Menu),
- new PageItem("Cursor",() => new CursorPage(), Icons.Cursor),
- new PageItem("Custom Drawing",() => new CustomDrawing(), Icons.Brush),
- new PageItem("DataGrid",() => new DataGridPage(), Icons.Grid),
- new PageItem("Data Validation",() => new DataValidationPage(), Icons.Shield),
- new PageItem("Date/Time Picker",() => new DateTimePickerPage(), Icons.Clock),
- new PageItem("CalendarDatePicker",() => new CalendarDatePickerPage(), Icons.Calendar),
- new PageItem("Dialogs",() => new DialogsPage(), Icons.Dialog),
- new PageItem("Drag+Drop",() => new DragAndDropPage(), Icons.DragDrop),
- new PageItem("DrawerPage",() => new DrawerDemoPage(), Icons.Drawer),
- new PageItem("Expander",() => new ExpanderPage(), Icons.Expand),
- new PageItem("Flyouts",() => new FlyoutsPage(), Icons.Flyout),
- new PageItem("Focus",() => new FocusPage(), Icons.Target),
- new PageItem("Gestures",() => new GesturePage(), Icons.Gesture),
- new PageItem("Image",() => new ImagePage(), Icons.Image),
- new PageItem("Label",() => new LabelsPage(), Icons.Tag),
- new PageItem("LayoutTransformControl",() => new LayoutTransformControlPage(), Icons.Transform),
- new PageItem("ListBox",() => new ListBoxPage(), Icons.List),
- new PageItem("Menu",() => new MenuPage(), Icons.Menu),
- new PageItem("NavigationPage",() => new NavigationDemoPage(), Icons.Navigation),
- new PageItem("Notifications",() => new NotificationsPage(), Icons.Bell),
- new PageItem("NumericUpDown",() => new NumericUpDownPage(), Icons.Number),
- new PageItem("OpenGL",() => new OpenGlPage(), Icons.Cube3D),
- new PageItem("OpenGL Lease",() => new OpenGlLeasePage(), Icons.Cube3D),
- new PageItem("PipsPager",() => new PipsPagerPage(), Icons.HorizontalDots),
- new PageItem("Platform Information",() => new PlatformInfoPage(), Icons.Info),
- new PageItem("Pointers",() => new PointersPage(), Icons.Cursor),
- new PageItem("ProgressBar",() => new ProgressBarPage(), Icons.Progress),
- new PageItem("RadioButton",() => new RadioButtonPage(), Icons.Radio),
- new PageItem("RefreshContainer",() => new RefreshContainerPage(), Icons.Refresh),
- new PageItem("RelativePanel",() => new RelativePanelPage(), Icons.Layout),
- new PageItem("ScrollViewer",() => new ScrollViewerPage(), Icons.Scroll),
- new PageItem("Slider",() => new SliderPage(), Icons.Tune),
- new PageItem("SplitView",() => new SplitViewPage(), Icons.Split),
- new PageItem("TabbedPage",() => new TabbedDemoPage(), Icons.Tab),
- new PageItem("TabControl",() => new TabControlPage(), Icons.Tab),
- new PageItem("TabStrip",() => new TabStripPage(), Icons.Tab),
- new PageItem("TextBox",() => new TextBoxPage(), Icons.TextInput),
- new PageItem("TextBlock",() => new TextBlockPage(), Icons.TextInput),
- new PageItem("Theme Variants",() => new ThemePage(), Icons.Theme),
- new PageItem("ToggleSwitch",() => new ToggleSwitchPage(), Icons.Toggle),
- new PageItem("ToolTip",() => new ToolTipPage(), Icons.Tooltip),
- new PageItem("TransitioningContentControl",() => new TransitioningContentControlPage(), Icons.Transition),
- new PageItem("TreeView",() => new TreeViewPage(), Icons.Tree),
- new PageItem("Viewbox",() => new ViewboxPage(), Icons.Viewbox),
- new PageItem("Native Embed",() => new NativeEmbedPage(), Icons.Puzzle),
- new PageItem("Window Customizations",() => new WindowCustomizationsPage(), Icons.Window),
- new PageItem("HeaderedContentControl",() => new HeaderedContentPage(), Icons.Header),
- new PageItem("Screens",() => new ScreenPage(), Icons.Monitor),
+ new PageItem("Home", () => new HomePage(), Icons.Home, "Overview of everything in the catalog"),
+ new PageItem("Composition", () => new CompositionPage(), Icons.Layers, "Composition-layer animations and effects", "Media & Graphics"),
+ new PageItem("Accelerator", () => new AcceleratorPage(), Icons.Keyboard, "Keyboard shortcuts that invoke commands", "Interaction"),
+ new PageItem("Acrylic", () => new AcrylicPage(), Icons.Blur, "Translucent acrylic window materials", "Media & Graphics"),
+ new PageItem("AdornerLayer", () => new AdornerLayerPage(), Icons.Sparkle, "Overlay visuals on top of other controls", "Status & Feedback"),
+ new PageItem("AutoCompleteBox",() => new AutoCompleteBoxPage(), Icons.TextInput, "Text input with completion suggestions", "Text"),
+ new PageItem("Border",() => new BorderPage(), Icons.Border, "Decorate elements with borders and corner radii", "Layout"),
+ new PageItem("BitmapCache",() => new BitmapCachePage(), Icons.Lightning, "Cache visuals as bitmaps for performance", "Media & Graphics"),
+ new PageItem("Buttons",() => new ButtonsPage(), Icons.CursorClick, "Button, RepeatButton, ToggleButton and friends", "Basic Input"),
+ new PageItem("ButtonSpinner",() => new ButtonSpinnerPage(), Icons.Spinner, "Content with increment and decrement buttons", "Basic Input"),
+ new PageItem("Calendar",() => new CalendarPage(), Icons.Calendar, "A month calendar for selecting dates", "Date & Time"),
+ new PageItem("Canvas",() => new CanvasPage(), Icons.Canvas, "Position children at explicit coordinates", "Layout"),
+ new PageItem("CommandBar",() => new CommandBarPage(), Icons.Terminal, "A toolbar of commands with an overflow menu", "Menus & Flyouts"),
+ new PageItem("Carousel",() => new Pages.CarouselPage(), Icons.Slides, "Cycle through a collection of items", "Collections & Data"),
+ new PageItem("CarouselPage",() => new CarouselDemoPage(), Icons.Slides, "Swipeable page-based navigation", "Navigation & Pages"),
+ new PageItem("CheckBox",() => new CheckBoxPage(), Icons.Checkbox, "Two- and three-state check boxes", "Basic Input"),
+ new PageItem("Clipboard",() => new ClipboardPage(), Icons.Clipboard, "Read from and write to the system clipboard", "Interaction"),
+ new PageItem("ColorPicker",() => new ColorPickerPage(), Icons.Palette, "Pick colors from spectrum and palette views", "Basic Input"),
+ new PageItem("ComboBox",() => new ComboBoxPage(), Icons.Dropdown, "A drop-down list of selectable items", "Basic Input"),
+ new PageItem("Container Queries",() => new ContainerQueryPage(), Icons.Container, "Styles that respond to container size", "Layout"),
+ new PageItem("ContentPage",() => new ContentDemoPage(), Icons.Document, "A page that hosts a single content view", "Navigation & Pages"),
+ new PageItem("ContextFlyout",() => new ContextFlyoutPage(), Icons.Menu, "Attach flyouts shown on right-click", "Menus & Flyouts"),
+ new PageItem("ContextMenu",() => new ContextMenuPage(), Icons.Menu, "Traditional right-click context menus", "Menus & Flyouts"),
+ new PageItem("Cursor",() => new CursorPage(), Icons.Cursor, "Change the pointer cursor over elements", "Interaction"),
+ new PageItem("Custom Drawing",() => new CustomDrawing(), Icons.Brush, "Render custom geometry in code", "Media & Graphics"),
+ new PageItem("DataGrid",() => new DataGridPage(), Icons.Grid, "Tabular data with sorting and editing", "Collections & Data"),
+ new PageItem("Data Validation",() => new DataValidationPage(), Icons.Shield, "Display validation errors from bindings", "Status & Feedback"),
+ new PageItem("Date/Time Picker",() => new DateTimePickerPage(), Icons.Clock, "Spinner-style date and time pickers", "Date & Time"),
+ new PageItem("CalendarDatePicker",() => new CalendarDatePickerPage(), Icons.Calendar, "A date picker with a drop-down calendar", "Date & Time"),
+ new PageItem("Dialogs",() => new DialogsPage(), Icons.Dialog, "File pickers and modal dialog windows", "Status & Feedback"),
+ new PageItem("Drag+Drop",() => new DragAndDropPage(), Icons.DragDrop, "Drag data within and between applications", "Interaction"),
+ new PageItem("DrawerPage",() => new DrawerDemoPage(), Icons.Drawer, "A page with a sliding navigation drawer", "Navigation & Pages"),
+ new PageItem("Expander",() => new ExpanderPage(), Icons.Expand, "A header that expands to reveal content", "Layout"),
+ new PageItem("Flyouts",() => new FlyoutsPage(), Icons.Flyout, "Lightweight popups anchored to controls", "Menus & Flyouts"),
+ new PageItem("Focus",() => new FocusPage(), Icons.Target, "Track and control keyboard focus", "Interaction"),
+ new PageItem("Gestures",() => new GesturePage(), Icons.Gesture, "Tap, scroll and pinch gesture recognition", "Interaction"),
+ new PageItem("Image",() => new ImagePage(), Icons.Image, "Display bitmaps with different stretch modes", "Media & Graphics"),
+ new PageItem("Label",() => new LabelsPage(), Icons.Tag, "Captions with access keys for other controls", "Text"),
+ new PageItem("LayoutTransformControl",() => new LayoutTransformControlPage(), Icons.Transform, "Apply transforms that affect layout", "Layout"),
+ new PageItem("ListBox",() => new ListBoxPage(), Icons.List, "A selectable, virtualized list of items", "Collections & Data"),
+ new PageItem("Menu",() => new MenuPage(), Icons.Menu, "Menu bars with nested menu items", "Menus & Flyouts"),
+ new PageItem("NavigationPage",() => new NavigationDemoPage(), Icons.Navigation, "Stack-based page navigation", "Navigation & Pages"),
+ new PageItem("Notifications",() => new NotificationsPage(), Icons.Bell, "Toast-style in-app notifications", "Status & Feedback"),
+ new PageItem("NumericUpDown",() => new NumericUpDownPage(), Icons.Number, "Numeric input with spinner buttons", "Basic Input"),
+ new PageItem("OpenGL",() => new OpenGlPage(), Icons.Cube3D, "Embed custom OpenGL rendering", "Media & Graphics"),
+ new PageItem("OpenGL Lease",() => new OpenGlLeasePage(), Icons.Cube3D, "Low-level access to the OpenGL context", "Media & Graphics"),
+ new PageItem("PipsPager",() => new PipsPagerPage(), Icons.HorizontalDots, "Dot-style pager for paginated content", "Collections & Data"),
+ new PageItem("Platform Information",() => new PlatformInfoPage(), Icons.Info, "Runtime platform and capability info", "Window & Platform"),
+ new PageItem("Pointers",() => new PointersPage(), Icons.Cursor, "Raw pointer input and capture", "Interaction"),
+ new PageItem("ProgressBar",() => new ProgressBarPage(), Icons.Progress, "Determinate and indeterminate progress", "Status & Feedback"),
+ new PageItem("RadioButton",() => new RadioButtonPage(), Icons.Radio, "Mutually exclusive option groups", "Basic Input"),
+ new PageItem("RefreshContainer",() => new RefreshContainerPage(), Icons.Refresh, "Pull-to-refresh for scrollable content", "Collections & Data"),
+ new PageItem("RelativePanel",() => new RelativePanelPage(), Icons.Layout, "Arrange children relative to each other", "Layout"),
+ new PageItem("ScrollViewer",() => new ScrollViewerPage(), Icons.Scroll, "Scrollable viewport over large content", "Layout"),
+ new PageItem("Slider",() => new SliderPage(), Icons.Tune, "Select a value from a continuous range", "Basic Input"),
+ new PageItem("SplitView",() => new SplitViewPage(), Icons.Split, "A collapsible pane beside content", "Navigation & Pages"),
+ new PageItem("TabbedPage",() => new TabbedDemoPage(), Icons.Tab, "Tab-based page navigation", "Navigation & Pages"),
+ new PageItem("TabControl",() => new TabControlPage(), Icons.Tab, "Switch between tabbed content views", "Navigation & Pages"),
+ new PageItem("TabStrip",() => new TabStripPage(), Icons.Tab, "A standalone strip of selectable tabs", "Navigation & Pages"),
+ new PageItem("TextBox",() => new TextBoxPage(), Icons.TextInput, "Single- and multi-line text editing", "Text"),
+ new PageItem("TextBlock",() => new TextBlockPage(), Icons.TextInput, "Styled read-only text display", "Text"),
+ new PageItem("Theme Variants",() => new ThemePage(), Icons.Theme, "Switch between light and dark variants", "Window & Platform"),
+ new PageItem("ToggleSwitch",() => new ToggleSwitchPage(), Icons.Toggle, "An on/off switch with a sliding knob", "Basic Input"),
+ new PageItem("ToolTip",() => new ToolTipPage(), Icons.Tooltip, "Hover hints for any control", "Status & Feedback"),
+ new PageItem("TransitioningContentControl",() => new TransitioningContentControlPage(), Icons.Transition, "Animate between content changes", "Media & Graphics"),
+ new PageItem("TreeView",() => new TreeViewPage(), Icons.Tree, "Hierarchical data with expandable nodes", "Collections & Data"),
+ new PageItem("Viewbox",() => new ViewboxPage(), Icons.Viewbox, "Scale content to fit available space", "Layout"),
+ new PageItem("Native Embed",() => new NativeEmbedPage(), Icons.Puzzle, "Host native platform controls", "Window & Platform"),
+ new PageItem("Window Customizations",() => new WindowCustomizationsPage(), Icons.Window, "Custom chrome, decorations and sizing", "Window & Platform"),
+ new PageItem("HeaderedContentControl",() => new HeaderedContentPage(), Icons.Header, "Content paired with a header", "Layout"),
+ new PageItem("Screens",() => new ScreenPage(), Icons.Monitor, "Enumerate displays and their bounds", "Window & Platform"),
};
+ /// Section order for the home page card grid.
+ private static readonly string[] s_categoryOrder =
+ {
+ "Basic Input",
+ "Text",
+ "Collections & Data",
+ "Date & Time",
+ "Menus & Flyouts",
+ "Navigation & Pages",
+ "Layout",
+ "Media & Graphics",
+ "Status & Feedback",
+ "Interaction",
+ "Window & Platform",
+ };
+
+ private IReadOnlyList? _homeSections;
+
+ public IReadOnlyList HomeSections => _homeSections ??=
+ s_categoryOrder
+ .Select(category => new HomeSection(category, _items.Where(i => i.Category == category).ToArray()))
+ .Where(section => section.Items.Count > 0)
+ .ToArray();
+
+ public void NavigateToPage(PageItem item)
+ {
+ // Clear any active search so the target is present in the filtered list.
+ if (!string.IsNullOrEmpty(Query))
+ Query = "";
+
+ var index = Pages.IndexOf(item);
+ if (index >= 0)
+ SelectedPageIndex = index;
+ }
+
public AvaloniaList Pages { get; } = new AvaloniaList();
public void Filter(string? query = "")
@@ -206,11 +242,19 @@ namespace ControlCatalog.ViewModels
}
}
- class PageItem(string header, Func