Restructured sample pages folder
This commit is contained in:
79
TodoApp/Pages/NewTodoPage.xaml
Normal file
79
TodoApp/Pages/NewTodoPage.xaml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TodoApp.NewTodoPage"
|
||||
Title="New Task"
|
||||
BackgroundColor="#F5F7FA">
|
||||
|
||||
<ContentPage.Resources>
|
||||
<Color x:Key="PrimaryColor">#5C6BC0</Color>
|
||||
<Color x:Key="AccentColor">#26A69A</Color>
|
||||
<Color x:Key="TextPrimary">#212121</Color>
|
||||
<Color x:Key="TextSecondary">#757575</Color>
|
||||
<Color x:Key="CardBackground">#FFFFFF</Color>
|
||||
<Color x:Key="BorderColor">#E8EAF6</Color>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Save" Clicked="OnSaveClicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,*" RowSpacing="16" Padding="20">
|
||||
|
||||
<!-- Header -->
|
||||
<VerticalStackLayout Grid.Row="0" Spacing="4">
|
||||
<Label Text="Create a new task"
|
||||
FontSize="24"
|
||||
TextColor="{StaticResource TextPrimary}" />
|
||||
<Label Text="Fill in the details below"
|
||||
FontSize="14"
|
||||
TextColor="{StaticResource TextSecondary}" />
|
||||
</VerticalStackLayout>
|
||||
|
||||
<!-- Title Section -->
|
||||
<VerticalStackLayout Grid.Row="1" Spacing="8">
|
||||
<Label Text="TITLE"
|
||||
FontSize="13"
|
||||
FontAttributes="Bold"
|
||||
TextColor="{StaticResource PrimaryColor}" />
|
||||
<Border BackgroundColor="{StaticResource CardBackground}"
|
||||
Stroke="{StaticResource BorderColor}"
|
||||
StrokeThickness="1"
|
||||
Padding="16,12">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="10" />
|
||||
</Border.StrokeShape>
|
||||
<Entry x:Name="TitleEntry"
|
||||
Placeholder="What needs to be done?"
|
||||
FontSize="18"
|
||||
TextColor="{StaticResource TextPrimary}"
|
||||
PlaceholderColor="{StaticResource TextSecondary}" />
|
||||
</Border>
|
||||
</VerticalStackLayout>
|
||||
|
||||
<!-- Notes Label -->
|
||||
<Label Grid.Row="2"
|
||||
Text="NOTES"
|
||||
FontSize="13"
|
||||
FontAttributes="Bold"
|
||||
TextColor="{StaticResource PrimaryColor}" />
|
||||
|
||||
<!-- Notes Section (fills remaining space) -->
|
||||
<Border Grid.Row="3"
|
||||
BackgroundColor="{StaticResource CardBackground}"
|
||||
Stroke="{StaticResource BorderColor}"
|
||||
StrokeThickness="1"
|
||||
Padding="16,12">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="10" />
|
||||
</Border.StrokeShape>
|
||||
<Editor x:Name="NotesEditor"
|
||||
Placeholder="Add notes (optional)..."
|
||||
FontSize="14"
|
||||
TextColor="{StaticResource TextPrimary}"
|
||||
PlaceholderColor="{StaticResource TextSecondary}"
|
||||
VerticalOptions="Fill" />
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
31
TodoApp/Pages/NewTodoPage.xaml.cs
Normal file
31
TodoApp/Pages/NewTodoPage.xaml.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// NewTodoPage - Create a new todo item
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
106
TodoApp/Pages/TodoDetailPage.xaml
Normal file
106
TodoApp/Pages/TodoDetailPage.xaml
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TodoApp.TodoDetailPage"
|
||||
Title="Task Details"
|
||||
BackgroundColor="#F5F7FA">
|
||||
|
||||
<ContentPage.Resources>
|
||||
<Color x:Key="PrimaryColor">#5C6BC0</Color>
|
||||
<Color x:Key="AccentColor">#26A69A</Color>
|
||||
<Color x:Key="DangerColor">#EF5350</Color>
|
||||
<Color x:Key="TextPrimary">#212121</Color>
|
||||
<Color x:Key="TextSecondary">#757575</Color>
|
||||
<Color x:Key="CardBackground">#FFFFFF</Color>
|
||||
<Color x:Key="BorderColor">#E8EAF6</Color>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="Delete" Clicked="OnDeleteClicked" />
|
||||
<ToolbarItem Text="Save" Clicked="OnSaveClicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<Grid RowDefinitions="Auto,Auto,*,Auto,Auto" RowSpacing="16" Padding="20">
|
||||
|
||||
<!-- Title Section -->
|
||||
<VerticalStackLayout Grid.Row="0" Spacing="8">
|
||||
<Label Text="TITLE"
|
||||
FontSize="13"
|
||||
FontAttributes="Bold"
|
||||
TextColor="{StaticResource PrimaryColor}" />
|
||||
<Border BackgroundColor="{StaticResource CardBackground}"
|
||||
Stroke="{StaticResource BorderColor}"
|
||||
StrokeThickness="1"
|
||||
Padding="16,12">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="10" />
|
||||
</Border.StrokeShape>
|
||||
<Entry x:Name="TitleEntry"
|
||||
Placeholder="Task title"
|
||||
FontSize="18"
|
||||
TextColor="{StaticResource TextPrimary}"
|
||||
PlaceholderColor="{StaticResource TextSecondary}" />
|
||||
</Border>
|
||||
</VerticalStackLayout>
|
||||
|
||||
<!-- Notes Label -->
|
||||
<Label Grid.Row="1"
|
||||
Text="NOTES"
|
||||
FontSize="13"
|
||||
FontAttributes="Bold"
|
||||
TextColor="{StaticResource PrimaryColor}" />
|
||||
|
||||
<!-- Notes Section (fills remaining space) -->
|
||||
<Border Grid.Row="2"
|
||||
BackgroundColor="{StaticResource CardBackground}"
|
||||
Stroke="{StaticResource BorderColor}"
|
||||
StrokeThickness="1"
|
||||
Padding="16,12">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="10" />
|
||||
</Border.StrokeShape>
|
||||
<Editor x:Name="NotesEditor"
|
||||
Placeholder="Add notes here..."
|
||||
FontSize="14"
|
||||
TextColor="{StaticResource TextPrimary}"
|
||||
PlaceholderColor="{StaticResource TextSecondary}"
|
||||
VerticalOptions="Fill" />
|
||||
</Border>
|
||||
|
||||
<!-- Status Section -->
|
||||
<VerticalStackLayout Grid.Row="3" Spacing="8">
|
||||
<Label Text="STATUS"
|
||||
FontSize="13"
|
||||
FontAttributes="Bold"
|
||||
TextColor="{StaticResource PrimaryColor}" />
|
||||
<Border BackgroundColor="{StaticResource CardBackground}"
|
||||
Stroke="{StaticResource BorderColor}"
|
||||
StrokeThickness="1"
|
||||
Padding="16,12">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="10" />
|
||||
</Border.StrokeShape>
|
||||
<HorizontalStackLayout Spacing="12">
|
||||
<CheckBox x:Name="CompletedCheckBox"
|
||||
Color="{StaticResource AccentColor}"
|
||||
VerticalOptions="Center"
|
||||
CheckedChanged="OnCompletedChanged" />
|
||||
<Label x:Name="StatusLabel"
|
||||
Text="In Progress"
|
||||
FontSize="16"
|
||||
TextColor="{StaticResource TextPrimary}"
|
||||
VerticalOptions="Center" />
|
||||
</HorizontalStackLayout>
|
||||
</Border>
|
||||
</VerticalStackLayout>
|
||||
|
||||
<!-- Created Date -->
|
||||
<Label Grid.Row="4"
|
||||
x:Name="CreatedLabel"
|
||||
FontSize="13"
|
||||
TextColor="{StaticResource TextSecondary}"
|
||||
HorizontalOptions="Center"
|
||||
HorizontalTextAlignment="Center" />
|
||||
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
91
TodoApp/Pages/TodoDetailPage.xaml.cs
Normal file
91
TodoApp/Pages/TodoDetailPage.xaml.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
// TodoDetailPage - View and edit a todo item
|
||||
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Platform;
|
||||
|
||||
namespace TodoApp;
|
||||
|
||||
public partial class TodoDetailPage : ContentPage
|
||||
{
|
||||
private readonly TodoItem _todo;
|
||||
private readonly TodoService _service = TodoService.Instance;
|
||||
|
||||
// Colors for status label
|
||||
private static readonly Color AccentColor = Color.FromArgb("#26A69A");
|
||||
private static readonly Color TextPrimary = Color.FromArgb("#212121");
|
||||
|
||||
public TodoDetailPage(TodoItem todo)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"[TodoDetailPage] Constructor starting for: {todo.Title}");
|
||||
InitializeComponent();
|
||||
Console.WriteLine($"[TodoDetailPage] InitializeComponent complete");
|
||||
|
||||
_todo = todo;
|
||||
|
||||
// Populate fields
|
||||
Console.WriteLine($"[TodoDetailPage] Setting TitleEntry.Text");
|
||||
TitleEntry.Text = _todo.Title;
|
||||
Console.WriteLine($"[TodoDetailPage] Setting NotesEditor.Text");
|
||||
NotesEditor.Text = _todo.Notes;
|
||||
Console.WriteLine($"[TodoDetailPage] Setting CompletedCheckBox.IsChecked");
|
||||
CompletedCheckBox.IsChecked = _todo.IsCompleted;
|
||||
Console.WriteLine($"[TodoDetailPage] Calling UpdateStatusLabel");
|
||||
UpdateStatusLabel(_todo.IsCompleted);
|
||||
Console.WriteLine($"[TodoDetailPage] Setting CreatedLabel.Text");
|
||||
CreatedLabel.Text = $"Created {_todo.CreatedAt:MMMM d, yyyy} at {_todo.CreatedAt:h:mm tt}";
|
||||
Console.WriteLine($"[TodoDetailPage] Constructor complete");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[TodoDetailPage] EXCEPTION in constructor: {ex.GetType().Name}: {ex.Message}");
|
||||
Console.WriteLine($"[TodoDetailPage] Stack trace: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCompletedChanged(object? sender, Microsoft.Maui.Controls.CheckedChangedEventArgs e)
|
||||
{
|
||||
Console.WriteLine($"[TodoDetailPage] OnCompletedChanged: {e.Value}");
|
||||
UpdateStatusLabel(e.Value);
|
||||
}
|
||||
|
||||
private void UpdateStatusLabel(bool isCompleted)
|
||||
{
|
||||
if (StatusLabel == null)
|
||||
{
|
||||
Console.WriteLine($"[TodoDetailPage] UpdateStatusLabel: StatusLabel is null, skipping");
|
||||
return;
|
||||
}
|
||||
Console.WriteLine($"[TodoDetailPage] UpdateStatusLabel: setting to {(isCompleted ? "Completed" : "In Progress")}");
|
||||
StatusLabel.Text = isCompleted ? "Completed" : "In Progress";
|
||||
StatusLabel.TextColor = isCompleted ? AccentColor : TextPrimary;
|
||||
}
|
||||
|
||||
private async void OnSaveClicked(object? sender, EventArgs e)
|
||||
{
|
||||
_todo.Title = TitleEntry.Text ?? "";
|
||||
_todo.Notes = NotesEditor.Text ?? "";
|
||||
_todo.IsCompleted = CompletedCheckBox.IsChecked;
|
||||
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
|
||||
private async void OnDeleteClicked(object? sender, EventArgs e)
|
||||
{
|
||||
// Show confirmation dialog
|
||||
var confirmed = await LinuxDialogService.ShowAlertAsync(
|
||||
"Delete Task",
|
||||
$"Are you sure you want to delete \"{_todo.Title}\"? This action cannot be undone.",
|
||||
"Delete",
|
||||
"Cancel");
|
||||
|
||||
if (confirmed)
|
||||
{
|
||||
_service.DeleteTodo(_todo);
|
||||
await Navigation.PopAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
129
TodoApp/Pages/TodoListPage.xaml
Normal file
129
TodoApp/Pages/TodoListPage.xaml
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TodoApp"
|
||||
x:Class="TodoApp.TodoListPage"
|
||||
Title="My Tasks"
|
||||
BackgroundColor="#F5F7FA">
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<!-- Colors -->
|
||||
<Color x:Key="PrimaryColor">#5C6BC0</Color>
|
||||
<Color x:Key="PrimaryDark">#3949AB</Color>
|
||||
<Color x:Key="AccentColor">#26A69A</Color>
|
||||
<Color x:Key="TextPrimary">#212121</Color>
|
||||
<Color x:Key="TextSecondary">#757575</Color>
|
||||
<Color x:Key="CardBackground">#FFFFFF</Color>
|
||||
<Color x:Key="DividerColor">#E0E0E0</Color>
|
||||
<Color x:Key="CompletedColor">#9E9E9E</Color>
|
||||
|
||||
<!-- Converters -->
|
||||
<local:AlternatingRowColorConverter x:Key="AlternatingRowColorConverter" />
|
||||
<local:CompletedToColorConverter x:Key="CompletedToColorConverter" />
|
||||
<local:CompletedToTextDecorationsConverter x:Key="CompletedToTextDecorationsConverter" />
|
||||
<local:CompletedToOpacityConverter x:Key="CompletedToOpacityConverter" />
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="+ Add" Clicked="OnAddClicked" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<Grid RowDefinitions="*,Auto" Padding="0">
|
||||
|
||||
<!-- Task List -->
|
||||
<CollectionView Grid.Row="0"
|
||||
x:Name="TodoCollectionView"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="OnSelectionChanged"
|
||||
VerticalOptions="FillAndExpand"
|
||||
BackgroundColor="Transparent"
|
||||
Margin="16,16,16,0">
|
||||
|
||||
<CollectionView.EmptyView>
|
||||
<VerticalStackLayout VerticalOptions="Center"
|
||||
HorizontalOptions="Center"
|
||||
Padding="40">
|
||||
<Label Text="No tasks yet"
|
||||
FontSize="22"
|
||||
TextColor="{StaticResource TextSecondary}"
|
||||
HorizontalOptions="Center" />
|
||||
<Label Text="Tap '+ Add' to create your first task"
|
||||
FontSize="14"
|
||||
TextColor="{StaticResource TextSecondary}"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0,8,0,0" />
|
||||
</VerticalStackLayout>
|
||||
</CollectionView.EmptyView>
|
||||
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:TodoItem">
|
||||
<!-- Card-style item -->
|
||||
<Grid Padding="0,6" BackgroundColor="Transparent">
|
||||
<Border StrokeThickness="0"
|
||||
BackgroundColor="{StaticResource CardBackground}"
|
||||
Padding="16,14"
|
||||
Opacity="{Binding IsCompleted, Converter={StaticResource CompletedToOpacityConverter}}">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="12" />
|
||||
</Border.StrokeShape>
|
||||
|
||||
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="16">
|
||||
<!-- Completion indicator -->
|
||||
<Border Grid.Column="0"
|
||||
WidthRequest="8"
|
||||
HeightRequest="44"
|
||||
Margin="0"
|
||||
BackgroundColor="{Binding IsCompleted, Converter={StaticResource CompletedToColorConverter}, ConverterParameter=indicator}"
|
||||
VerticalOptions="Center">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="4" />
|
||||
</Border.StrokeShape>
|
||||
</Border>
|
||||
|
||||
<!-- Content -->
|
||||
<VerticalStackLayout Grid.Column="1"
|
||||
Spacing="4"
|
||||
VerticalOptions="Center">
|
||||
<!-- Title -->
|
||||
<Label Text="{Binding Title}"
|
||||
FontSize="16"
|
||||
TextColor="{Binding IsCompleted, Converter={StaticResource CompletedToColorConverter}}"
|
||||
TextDecorations="{Binding IsCompleted, Converter={StaticResource CompletedToTextDecorationsConverter}}" />
|
||||
|
||||
<!-- Notes preview -->
|
||||
<Label Text="{Binding Notes}"
|
||||
FontSize="13"
|
||||
TextColor="{Binding IsCompleted, Converter={StaticResource CompletedToColorConverter}, ConverterParameter=notes}"
|
||||
MaxLines="2"
|
||||
LineBreakMode="TailTruncation" />
|
||||
</VerticalStackLayout>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
<!-- Footer Stats -->
|
||||
<Border Grid.Row="1"
|
||||
BackgroundColor="{StaticResource PrimaryColor}"
|
||||
StrokeThickness="0"
|
||||
Padding="24,14"
|
||||
Margin="0">
|
||||
<Grid ColumnDefinitions="Auto,Auto" ColumnSpacing="6" HorizontalOptions="Center" VerticalOptions="Center">
|
||||
<Label Grid.Column="0"
|
||||
Text="Tasks:"
|
||||
FontSize="15"
|
||||
TextColor="White" />
|
||||
<Label Grid.Column="1"
|
||||
x:Name="StatsLabel"
|
||||
FontSize="15"
|
||||
TextColor="White"
|
||||
Opacity="0.9" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
174
TodoApp/Pages/TodoListPage.xaml.cs
Normal file
174
TodoApp/Pages/TodoListPage.xaml.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
// TodoListPage - Main page for viewing todos with XAML support
|
||||
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace TodoApp;
|
||||
|
||||
public partial class TodoListPage : ContentPage
|
||||
{
|
||||
private readonly TodoService _service = TodoService.Instance;
|
||||
|
||||
public TodoListPage()
|
||||
{
|
||||
Console.WriteLine("[TodoListPage] Constructor starting");
|
||||
InitializeComponent();
|
||||
|
||||
TodoCollectionView.ItemsSource = _service.Todos;
|
||||
UpdateStats();
|
||||
|
||||
Console.WriteLine("[TodoListPage] Constructor finished");
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
Console.WriteLine("[TodoListPage] OnAppearing called - refreshing CollectionView");
|
||||
base.OnAppearing();
|
||||
|
||||
// Refresh indexes for alternating row colors
|
||||
_service.RefreshIndexes();
|
||||
|
||||
// Refresh the collection view
|
||||
TodoCollectionView.ItemsSource = null;
|
||||
TodoCollectionView.ItemsSource = _service.Todos;
|
||||
Console.WriteLine($"[TodoListPage] ItemsSource set with {_service.Todos.Count} items");
|
||||
UpdateStats();
|
||||
}
|
||||
|
||||
private async void OnAddClicked(object sender, EventArgs e)
|
||||
{
|
||||
await Navigation.PushAsync(new NewTodoPage());
|
||||
}
|
||||
|
||||
private async void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"[TodoListPage] OnSelectionChanged: {e.CurrentSelection.Count} items selected");
|
||||
if (e.CurrentSelection.FirstOrDefault() is TodoItem todo)
|
||||
{
|
||||
Console.WriteLine($"[TodoListPage] Navigating to TodoDetailPage for: {todo.Title}");
|
||||
TodoCollectionView.SelectedItem = null; // Deselect
|
||||
var detailPage = new TodoDetailPage(todo);
|
||||
Console.WriteLine($"[TodoListPage] Created TodoDetailPage, pushing...");
|
||||
await Navigation.PushAsync(detailPage);
|
||||
Console.WriteLine($"[TodoListPage] Navigation complete");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[TodoListPage] EXCEPTION in OnSelectionChanged: {ex.GetType().Name}: {ex.Message}");
|
||||
Console.WriteLine($"[TodoListPage] Stack trace: {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStats()
|
||||
{
|
||||
var completed = _service.CompletedCount;
|
||||
var total = _service.TotalCount;
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
StatsLabel.Text = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
StatsLabel.Text = $"{completed} of {total} completed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converter for alternating row background colors.
|
||||
/// </summary>
|
||||
public class AlternatingRowColorConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is int index)
|
||||
{
|
||||
return index % 2 == 0 ? Colors.White : Color.FromArgb("#F5F5F5");
|
||||
}
|
||||
return Colors.White;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converter for completed task text color and indicator color.
|
||||
/// </summary>
|
||||
public class CompletedToColorConverter : IValueConverter
|
||||
{
|
||||
// Define colors
|
||||
private static readonly Color PrimaryColor = Color.FromArgb("#5C6BC0");
|
||||
private static readonly Color AccentColor = Color.FromArgb("#26A69A");
|
||||
private static readonly Color CompletedColor = Color.FromArgb("#9E9E9E");
|
||||
private static readonly Color TextPrimary = Color.FromArgb("#212121");
|
||||
private static readonly Color TextSecondary = Color.FromArgb("#757575");
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
bool isCompleted = value is bool b && b;
|
||||
string param = parameter as string ?? "";
|
||||
|
||||
// Indicator bar color
|
||||
if (param == "indicator")
|
||||
{
|
||||
return isCompleted ? CompletedColor : AccentColor;
|
||||
}
|
||||
|
||||
// Text colors
|
||||
if (isCompleted)
|
||||
{
|
||||
return CompletedColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return param == "notes" ? TextSecondary : TextPrimary;
|
||||
}
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converter for completed task text decorations (strikethrough).
|
||||
/// </summary>
|
||||
public class CompletedToTextDecorationsConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
bool isCompleted = value is bool b && b;
|
||||
return isCompleted ? TextDecorations.Strikethrough : TextDecorations.None;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converter for completed task opacity (slightly faded when complete).
|
||||
/// </summary>
|
||||
public class CompletedToOpacityConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
bool isCompleted = value is bool b && b;
|
||||
return isCompleted ? 0.7 : 1.0;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user