diff --git a/samples/TodoApp/App.xaml b/samples/TodoApp/App.xaml
new file mode 100644
index 0000000..8857dfd
--- /dev/null
+++ b/samples/TodoApp/App.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+ #5C6BC0
+ #3949AB
+ #26A69A
+ #EF5350
+
+
+ #F5F5F5
+ #1E1E1E
+
+
+ #FFFFFF
+ #2D2D2D
+
+
+ #FFFFFF
+ #3D3D3D
+
+
+ #212121
+ #FFFFFF
+ #757575
+ #B0B0B0
+
+
+ #E0E0E0
+ #424242
+
+
+ #5C6BC0
+ #3949AB
+
+
+
diff --git a/samples/TodoApp/App.xaml.cs b/samples/TodoApp/App.xaml.cs
new file mode 100644
index 0000000..fc6342f
--- /dev/null
+++ b/samples/TodoApp/App.xaml.cs
@@ -0,0 +1,14 @@
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Controls;
+
+namespace TodoApp;
+
+public partial class App : Application
+{
+ public App()
+ {
+ InitializeComponent();
+ UserAppTheme = AppTheme.Light;
+ MainPage = new NavigationPage(new TodoListPage());
+ }
+}
diff --git a/samples/TodoApp/MauiProgram.cs b/samples/TodoApp/MauiProgram.cs
new file mode 100644
index 0000000..88f0243
--- /dev/null
+++ b/samples/TodoApp/MauiProgram.cs
@@ -0,0 +1,24 @@
+using Microsoft.Maui;
+using Microsoft.Maui.Controls.Hosting;
+using Microsoft.Maui.Hosting;
+using Microsoft.Maui.Platform.Linux.Hosting;
+
+namespace TodoApp;
+
+public static class MauiProgram
+{
+ public static MauiApp CreateMauiApp()
+ {
+ var builder = MauiApp.CreateBuilder();
+ builder
+ .UseMauiApp()
+ .UseLinuxPlatform()
+ .ConfigureFonts(fonts =>
+ {
+ fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
+ fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
+ });
+
+ return builder.Build();
+ }
+}
diff --git a/samples/TodoApp/NewTodoPage.xaml b/samples/TodoApp/NewTodoPage.xaml
new file mode 100644
index 0000000..9ee88fa
--- /dev/null
+++ b/samples/TodoApp/NewTodoPage.xaml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/TodoApp/NewTodoPage.xaml.cs b/samples/TodoApp/NewTodoPage.xaml.cs
new file mode 100644
index 0000000..5a6f80f
--- /dev/null
+++ b/samples/TodoApp/NewTodoPage.xaml.cs
@@ -0,0 +1,29 @@
+using System;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Graphics;
+
+namespace TodoApp;
+
+public partial class NewTodoPage : ContentPage
+{
+ private readonly TodoService _service = TodoService.Instance;
+
+ public NewTodoPage()
+ {
+ InitializeComponent();
+ }
+
+ private async void OnSaveClicked(object? sender, EventArgs e)
+ {
+ var title = TitleEntry.Text?.Trim();
+ if (string.IsNullOrEmpty(title))
+ {
+ TitleEntry.Placeholder = "Title is required!";
+ TitleEntry.PlaceholderColor = Colors.Red;
+ return;
+ }
+
+ _service.AddTodo(title, NotesEditor.Text ?? "");
+ await Navigation.PopAsync();
+ }
+}
diff --git a/samples/TodoApp/Program.cs b/samples/TodoApp/Program.cs
new file mode 100644
index 0000000..318d9f7
--- /dev/null
+++ b/samples/TodoApp/Program.cs
@@ -0,0 +1,12 @@
+using Microsoft.Maui.Platform.Linux.Hosting;
+
+namespace TodoApp;
+
+public class Program
+{
+ [STAThread]
+ public static void Main(string[] args)
+ {
+ LinuxProgramHost.Run(args, MauiProgram.CreateMauiApp);
+ }
+}
diff --git a/samples/TodoApp/Resources/Images/icon_add_light.svg b/samples/TodoApp/Resources/Images/icon_add_light.svg
new file mode 100644
index 0000000..09a77b9
--- /dev/null
+++ b/samples/TodoApp/Resources/Images/icon_add_light.svg
@@ -0,0 +1,4 @@
+
diff --git a/samples/TodoApp/Resources/Images/icon_delete_light.svg b/samples/TodoApp/Resources/Images/icon_delete_light.svg
new file mode 100644
index 0000000..5d366f3
--- /dev/null
+++ b/samples/TodoApp/Resources/Images/icon_delete_light.svg
@@ -0,0 +1,6 @@
+
diff --git a/samples/TodoApp/Resources/Images/icon_save_light.svg b/samples/TodoApp/Resources/Images/icon_save_light.svg
new file mode 100644
index 0000000..5df4c5d
--- /dev/null
+++ b/samples/TodoApp/Resources/Images/icon_save_light.svg
@@ -0,0 +1,3 @@
+
diff --git a/samples/TodoApp/TodoApp.csproj b/samples/TodoApp/TodoApp.csproj
new file mode 100644
index 0000000..d735339
--- /dev/null
+++ b/samples/TodoApp/TodoApp.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net9.0
+ Exe
+ TodoApp
+ enable
+ enable
+ true
+ Todo App
+ com.openmaui.todoapp
+ 1.0
+ 9.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/TodoApp/TodoDetailPage.xaml b/samples/TodoApp/TodoDetailPage.xaml
new file mode 100644
index 0000000..8f78b20
--- /dev/null
+++ b/samples/TodoApp/TodoDetailPage.xaml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/TodoApp/TodoDetailPage.xaml.cs b/samples/TodoApp/TodoDetailPage.xaml.cs
new file mode 100644
index 0000000..65e22e0
--- /dev/null
+++ b/samples/TodoApp/TodoDetailPage.xaml.cs
@@ -0,0 +1,42 @@
+using System;
+using Microsoft.Maui.Controls;
+
+namespace TodoApp;
+
+public partial class TodoDetailPage : ContentPage
+{
+ private readonly TodoService _service = TodoService.Instance;
+ private readonly TodoItem _item;
+
+ public TodoDetailPage(TodoItem item)
+ {
+ InitializeComponent();
+ _item = item;
+
+ TitleEntry.Text = item.Title;
+ NotesEditor.Text = item.Notes;
+ CompletedCheckBox.IsChecked = item.IsCompleted;
+ CreatedLabel.Text = $"Created {item.CreatedAt:MMMM d, yyyy} at {item.CreatedAt:h:mm tt}";
+ }
+
+ private async void OnSaveClicked(object? sender, EventArgs e)
+ {
+ _item.Title = TitleEntry.Text ?? "";
+ _item.Notes = NotesEditor.Text ?? "";
+ _item.IsCompleted = CompletedCheckBox.IsChecked;
+ await Navigation.PopAsync();
+ }
+
+ private async void OnDeleteClicked(object? sender, EventArgs e)
+ {
+ bool confirm = await DisplayAlert("Delete Task",
+ "Are you sure you want to delete this task?",
+ "Delete", "Cancel");
+
+ if (confirm)
+ {
+ _service.RemoveTodo(_item);
+ await Navigation.PopAsync();
+ }
+ }
+}
diff --git a/samples/TodoApp/TodoItem.cs b/samples/TodoApp/TodoItem.cs
new file mode 100644
index 0000000..40a2a2a
--- /dev/null
+++ b/samples/TodoApp/TodoItem.cs
@@ -0,0 +1,47 @@
+using System;
+using System.ComponentModel;
+
+namespace TodoApp;
+
+public class TodoItem : INotifyPropertyChanged
+{
+ private string _title = "";
+ private string _notes = "";
+ private bool _isCompleted;
+ private int _index;
+
+ public int Id { get; set; }
+
+ public int Index
+ {
+ get => _index;
+ set { if (_index != value) { _index = value; OnPropertyChanged(nameof(Index)); } }
+ }
+
+ public string Title
+ {
+ get => _title;
+ set { if (_title != value) { _title = value; OnPropertyChanged(nameof(Title)); } }
+ }
+
+ public string Notes
+ {
+ get => _notes;
+ set { if (_notes != value) { _notes = value; OnPropertyChanged(nameof(Notes)); } }
+ }
+
+ public bool IsCompleted
+ {
+ get => _isCompleted;
+ set { if (_isCompleted != value) { _isCompleted = value; OnPropertyChanged(nameof(IsCompleted)); } }
+ }
+
+ public DateTime CreatedAt { get; set; } = DateTime.Now;
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected void OnPropertyChanged(string propertyName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+}
diff --git a/samples/TodoApp/TodoListPage.xaml b/samples/TodoApp/TodoListPage.xaml
new file mode 100644
index 0000000..9ff79c5
--- /dev/null
+++ b/samples/TodoApp/TodoListPage.xaml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/TodoApp/TodoListPage.xaml.cs b/samples/TodoApp/TodoListPage.xaml.cs
new file mode 100644
index 0000000..36cd72b
--- /dev/null
+++ b/samples/TodoApp/TodoListPage.xaml.cs
@@ -0,0 +1,69 @@
+using System;
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Controls;
+
+namespace TodoApp;
+
+public partial class TodoListPage : ContentPage
+{
+ private readonly TodoService _service = TodoService.Instance;
+ private bool _isNavigating;
+
+ public TodoListPage()
+ {
+ InitializeComponent();
+ TodoCollectionView.ItemsSource = _service.Todos;
+ UpdateStats();
+ ThemeSwitch.IsToggled = Application.Current?.UserAppTheme == AppTheme.Dark;
+ }
+
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ _isNavigating = false;
+ _service.RefreshIndexes();
+ TodoCollectionView.ItemsSource = null;
+ TodoCollectionView.ItemsSource = _service.Todos;
+ UpdateStats();
+ }
+
+ private void OnThemeToggled(object? sender, ToggledEventArgs e)
+ {
+ if (Application.Current != null)
+ {
+ Application.Current.UserAppTheme = e.Value ? AppTheme.Dark : AppTheme.Light;
+ // Refresh to apply theme
+ var items = TodoCollectionView.ItemsSource;
+ TodoCollectionView.ItemsSource = null;
+ TodoCollectionView.ItemsSource = items;
+ }
+ }
+
+ private async void OnAddClicked(object? sender, EventArgs e)
+ {
+ await Navigation.PushAsync(new NewTodoPage());
+ }
+
+ private async void OnItemTapped(object? sender, TappedEventArgs e)
+ {
+ if (_isNavigating || e.Parameter is not TodoItem todoItem)
+ return;
+
+ _isNavigating = true;
+ try
+ {
+ await Navigation.PushAsync(new TodoDetailPage(todoItem));
+ }
+ catch
+ {
+ _isNavigating = false;
+ }
+ }
+
+ private void UpdateStats()
+ {
+ int completed = _service.CompletedCount;
+ int total = _service.TotalCount;
+ StatsLabel.Text = total == 0 ? "" : $"Tasks: {completed} of {total}";
+ }
+}
diff --git a/samples/TodoApp/TodoService.cs b/samples/TodoApp/TodoService.cs
new file mode 100644
index 0000000..9fa8830
--- /dev/null
+++ b/samples/TodoApp/TodoService.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace TodoApp;
+
+public class TodoService
+{
+ private static TodoService? _instance;
+ public static TodoService Instance => _instance ??= new TodoService();
+
+ public ObservableCollection Todos { get; } = new();
+
+ private int _nextId = 1;
+
+ private TodoService()
+ {
+ // Add sample data
+ AddTodo("Learn OpenMaui Linux",
+ "Explore the SkiaSharp-based rendering engine for .NET MAUI on Linux desktop. " +
+ "This is a very long description that should wrap to multiple lines and demonstrate " +
+ "the ellipsis truncation feature when MaxLines is set to 2.");
+ AddTodo("Build amazing apps",
+ "Create cross-platform applications that run on Windows, macOS, iOS, Android, and Linux! " +
+ "With OpenMaui, you can write once and deploy everywhere.");
+ AddTodo("Share with the community",
+ "Contribute to the open-source project and help others build great Linux apps. " +
+ "Join our growing community of developers who are passionate about bringing .NET MAUI to Linux.");
+ }
+
+ public void AddTodo(string title, string notes)
+ {
+ var todo = new TodoItem
+ {
+ Id = _nextId++,
+ Title = title,
+ Notes = notes,
+ Index = Todos.Count
+ };
+ Todos.Add(todo);
+ }
+
+ public void RemoveTodo(TodoItem item)
+ {
+ Todos.Remove(item);
+ RefreshIndexes();
+ }
+
+ public void RefreshIndexes()
+ {
+ for (int i = 0; i < Todos.Count; i++)
+ {
+ Todos[i].Index = i;
+ }
+ }
+
+ public int CompletedCount => Todos.Count(t => t.IsCompleted);
+ public int TotalCount => Todos.Count;
+}