Hello again. It's become time to write a new article. At this time, I tell you how to create your own event on your mobile device with code. It can be helpful when you are parsing some data from some website, and you want to make a record of some information related to some event. I'll show you a super easy code for generating an iCal file, and you'll decide where to get data yourself.
Let's create a simple .NET MAUI project from the template:
dotnet new maui -n CalSample
It would be best to delete all redundant code from the generated project. After that, as you did it. You need to install package dotnet add package Ical.Net
, and also
you should go to the MainPage.xaml
file of your project. Between ContentPage tags, put StackLayout block, something like that:
<?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="CalSample.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<StackLayout Margin="20">
</StackLayout>
</ContentPage>
And now, let's make inputs for entry data:
<?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="CalSample.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<StackLayout Margin="20">
<!-- The event's title, which you'll see in the calendar -->
<Label Text="Event Summary" />
<Entry x:Name="SummaryEntry" Placeholder="Enter event summary" />
<!-- The event's start date -->
<Label Text="Start Date" />
<DatePicker x:Name="StartDatePicker" />
<!-- The event's end date -->
<Label Text="End Date" />
<DatePicker x:Name="EndDatePicker" />
<!-- The optional input of the event's repetition. -->
<Label Text="Recurrence Frequency" />
<Picker x:Name="FrequencyPicker">
<Picker.Items>
<x:String>None</x:String>
<x:String>Yearly</x:String>
<x:String>Monthly</x:String>
<x:String>Weekly</x:String>
<x:String>Daily</x:String>
</Picker.Items>
</Picker>
<!-- The interval between recurrences. -->
<Label Text="Recurrence Interval" />
<Entry x:Name="IntervalEntry" Placeholder="Enter interval (e.g., 1)" Keyboard="Numeric" />
<!-- The optional field for choosing a day of the week for the event's repetition. -->
<Label Text="Recurrence Day of Week" />
<Picker x:Name="DayOfWeekPicker">
<Picker.Items>
<x:String>None</x:String>
<x:String>Sunday</x:String>
<x:String>Monday</x:String>
<x:String>Tuesday</x:String>
<x:String>Wednesday</x:String>
<x:String>Thursday</x:String>
<x:String>Friday</x:String>
<x:String>Saturday</x:String>
</Picker.Items>
</Picker>
<!-- This param is for setting intervals between the days of the week; for example, if you selected -->
<!-- Friday and entered 2, it'll be applied for each second Friday. -->
<Label Text="Recurrence Offset" />
<Entry x:Name="OffsetEntry" Placeholder="Enter offset (e.g., 1)" Keyboard="Numeric" />
<!-- Until which date repeat event. -->
<Label Text="Recurrence End Date" />
<DatePicker x:Name="RecurrenceEndDatePicker" />
<!-- Send data -->
<Button Text="Generate iCal" Clicked="GenerateICalClicked" />
</StackLayout>
</ContentPage>
When our layout is complete, go to the MainPage.xaml.cs
file and put the method that sets entered data, generates an iCal file, and opens it.
private void GenerateICalClicked(object sender, EventArgs e)
{
string summary = SummaryEntry.Text;
DateTime startDate = StartDatePicker.Date;
DateTime endDate = EndDatePicker.Date;
FrequencyType frequency =
(FrequencyType)Enum.Parse(typeof(FrequencyType), FrequencyPicker.SelectedItem.ToString(), true);
int interval = Convert.ToInt32(IntervalEntry.Text);
DayOfWeek? dayOfWeek = DayOfWeekPicker.SelectedItem.ToString() == "None"
? null
: (DayOfWeek)Enum.Parse(typeof(DayOfWeek), DayOfWeekPicker.SelectedItem.ToString());
int offset = Convert.ToInt32(OffsetEntry.Text);
var recurrence = new RecurrencePattern
{
Frequency = frequency,
Interval = interval,
ByDay = dayOfWeek != null
? new List<WeekDay> { new WeekDay { DayOfWeek = dayOfWeek.Value, Offset = offset } }
: null,
Until = RecurrenceEndDatePicker.Date
};
var icalEvent = new CalendarEvent
{
Summary = summary,
Start = new CalDateTime(startDate.Year, startDate.Month, startDate.Day),
End = new CalDateTime(endDate.Year, endDate.Month, endDate.Day),
IsAllDay = true,
RecurrenceRules = new List<RecurrencePattern> { recurrence }
};
var calendar = new Calendar();
calendar.Events.Add(icalEvent);
var serializer = new CalendarSerializer();
string icalContent = serializer.SerializeToString(calendar);
string filePath = "event.ics";
string popoverTitle = "Read ical file";
string file = System.IO.Path.Combine(FileSystem.CacheDirectory, filePath);
System.IO.File.WriteAllText(file, icalContent);
Launcher.Default.OpenAsync(new OpenFileRequest(popoverTitle, new ReadOnlyFile(file))).ConfigureAwait(false);
}
And now, you can run it. I'll be running it on the Android platform. With iOS failing, my IDE doesn't support the new SDK. For Android, you also should install SDK and OS.
Run your proffered Android device.
After filling out the form, just press submit, and you'll see a dialog window suggesting adding an event to the calendar.
Tap "Add to Calendar" and go to the calendar on your device.
Tap by event.
It works fine. And now, as a bonus, I show you how it works on Mac OS Sonoma. I'll switch to MacOS runner.
Here, behavior is different. When you click to submit, the application suggests exporting the iCal file.
I'll export the file to Notes.
If we open the note and save this file, I'll open the file in a text editor. That is what the contents of the file look like.
BEGIN:VCALENDAR
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 4.0//EN
VERSION:2.0
BEGIN:VEVENT
DTEND;VALUE=DATE:20231009
DTSTAMP:20231008T085828Z
DTSTART;VALUE=DATE:20231008
RRULE:FREQ=MONTHLY;INTERVAL=2;UNTIL=20231130T000000;BYDAY=2FR
SEQUENCE:0
SUMMARY:Time to drink beer
UID:32495d52-591d-4843-9d0c-2d31a87657eb
END:VEVENT
END:VCALENDAR
If I double-click by file, the Calendar application will suggest adding a new event and selecting in which calendar.
If I open the event, I'll see this:
This example is super easy. Sure, you can make more complicated scenarios. I hope this article was helpful and exciting for you. See you in the following article. Happy coding!
The source code: REPO