Implementing Recurring Tasks Manager Using C# and AvaloniaUI
This post outlines the implementation of a recurring tasks manager using C# and AvaloniaUI.
The core idea involves recurring tasks, which are meant to be completed repeatedly over an indefinite period. The intervals between consecutive completions are intended to be roughly consistent, though there is no urgency nor deadlines: a recurring task can be completed a few days before or after its ideal date with no issues. The scheduling system is flexible; if a task is regularly completed ahead of its scheduled date, the scheduled interval will shrink. The app aim is to be able to handle thousands of tasks for all aspects of one's life.
Below is a screenshot of the completed app:
The source code is available on GitHub here.
Implementation Breakdown
This section details the implementation commit by commit.
The first commit initialises the repository with an empty solution, using a custom template that was discussed in last week's post.
All subsequent commits are part of the following pull request: https://github.com/yamesant/recurring-tasks-manager/pull/1
Modelling the Tasks
The second commit introduces the Task
class. Each task is identified by an Id
and has a Name
. Four additional properties support the scheduling process. Protected setters and a default constructor are required by EF Core, which will be added later to handle persistence.
In the third commit, task completion logic is implemented, along with the scheduling mechanism. The new estimated number of days until the next task completion is calculated as the average interval between prior completions.
The fourth commit adds some useful informational properties to the Task
class to be displayed in the view.
User Interface
The fifth commit sets up the user interface project using the Avalonia .NET MVVM App
template, with the ReactiveUI MVVM toolkit.
In the sixth commit, sample data is created and displayed in a list. All sample data is made-up yet plausible. The layout is inspired by the one seen in the Music Store App tutorial from Avalonia’s documentation. In both cases, items (tasks in this case, albums in the tutorial) are displayed as rectangles with rounded corners, arranged within a rectangular window, with some spacing between them. Here is a visual representation:
In the seventh commit, the view is customised to display all relevant task properties. Colour coding is introduced for quick visual reference: overdue tasks are marked in red, ready-to-complete tasks in green, and all others in grey. The varying background colours are achieved by displaying all background elements simultaneously, but with only the relevant one visible at any given time using an IsVisible
flag. Here is how it looks now:
The eighth commit sorts the tasks using Insertion Sort. Overdue and ready-to-complete tasks are prioritised at the top of the list. This ensures that the user does not need to scroll down to find them. The newly added AddTask
method must be called whenever the task list is manipulated to maintain the sorting order. Here is the new look:
Button Controls
This section covers the two must-have actions: adding a task and completing a task.
The ninth commit implements the CompleteTaskCommand
button. When a task is completed, it is removed from the list and immediately re-added. This keeps the tasks sorted. For example, completing the red "Clean the house" task sends it to the grey zone, and its completion counter increments by one:
The tenth commit introduces the AddTaskCommand
button. It launches a dialog (pop-up window) to gather input from the user necessary to create a task. The implementation is identical to that in the Music Store App tutorial.
Here is how adding a new task, "Go on vacation", looks like:
Data Persistence
Persistence is achieved using EF Core with a SQLite database, implemented in the eleventh commit. The implementation consists of three parts:
- The first part is migrations, which are set up using the
dotnet ef migrations add InitialCreate
command. - The second part is the
DbInitializer
class, which populates the database with sample data. - The third part is saving the changes whenever a task is completed or a new task is added.
The SQLite database file, recurring-tasks-manager.db
, can be found in the ./bin/Debug/net8.0
folder.
Conclusion
This post presents a prototype for a Recurring Tasks Manager app. There is still a lot more to do to transform it into a fully-fledged application. Future improvements could include enhancing the visual design, refining navigation, improving task management (e.g. allowing task deletions), introducing a task ideas hub, adding task history and completion statistics, and, of course, making the app publicly available.