175 lines
5.4 KiB
C#
175 lines
5.4 KiB
C#
// 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();
|
|
}
|
|
}
|