Create Project Planning and Resource Management Calendar in .NET MAUI
Tags: dotnet, csharp, mobile, maui
Published: 2023-01-10 13:35:54

---
title: Create Project Planning and Resource Management Calendar in .NET MAUI
published: true
date: 2023-01-05 10:23:47 UTC
tags: dotnet, csharp, mobile, maui
canonical_url: https://www.syncfusion.com/blogs/post/create-project-planning-and-resource-management-calendar-in-net-maui.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hquagxswuhgbx3w8svwm.png
---
A project planning calendar for resource scheduling is an effective project management tool. It makes it easier to plan, track, update, and collaborate on project tasks with your team. The [Syncfusion .NET MAUI Scheduler](https://www.syncfusion.com/maui-controls/maui-scheduler "Syncfusion .NET MAUI Scheduler") control allows you to create a real-time project planning and resource management calendar by using the resource view feature in timeline views.

In this blog, I’ll explain how to create a calendar for planning employees’ tasks using the Scheduler’s [timeline month view](https://help.syncfusion.com/maui/scheduler/timeline-views "Timeline Views in .NET MAUI Scheduler").
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Project-planning-calendar-in-.NET-MAUI-1.png" alt="Project planning calendar in .NET MAUI" style="width:100%">

  <figcaption>Project planning calendar in .NET MAUI</figcaption>

</figure>
**Note:** If you are new to using our .NET MAUI Scheduler control, please read the Getting Started with [.NET MAUI Scheduler documentation](https://help.syncfusion.com/maui/scheduler/getting-started "Getting Started with .NET MAUI Scheduler") before proceeding further.

## Designing the calendar for each resource

Create a calendar for each employee to schedule and manage their tasks in one place. The Scheduler resources feature can be used to manage tasks that the project team is planning to work on in the timeline day, timeline week, timeline workweek, and timeline month views.

Refer to the following code to initialize the scheduler timeline month view.

```xml
xmlns:schedule="clr-namespace:Syncfusion.Maui.Scheduler;assembly=Syncfusion.Maui.Scheduler"

 <schedule:SfScheduler x:Name="Scheduler" View="TimelineMonth"/>
```

### Create an employee model

It’s very simple to add a resource view to the Scheduler control. You can create any kind of object and bind it in the [Resources](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Resources "Resources property of .NET MAUI Scheduler") property of [SchedulerResourceView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html "SchedulerResourceView Class of .NET MAUI Scheduler") class.

Here, we have created a custom **Employee** resource model with the required fields **Id** , **Name** , and other optional fields like **Background** , **Role,** and **ImageName**.

```csharp
public class Employee
{
    /// <summary>
    /// Gets or sets employee name.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets resource object id.
    /// </summary>
    public object Id { get; set; }

    /// <summary>
    /// Gets or sets employee background.
    /// </summary>
    public Brush Background { get; set; }

    /// <summary>
    /// Gets or sets an image for an employee.
    /// </summary>
    public string ImageName { get; set; }

    /// <summary>
    /// Gets or sets employee role.
    /// </summary>
    public string Role { get; set; }
}
```

Then, map the custom **Employee** properties to the [Mapping](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Mapping "Mapping property of .NET MAUI Scheduler") properties of the [SchedulerResourceView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html "SchedulerResourceView Class of .NET MAUI Scheduler") class.

Refer to the following code.

```xml
<schedule:SfScheduler x:Name="Scheduler" View="TimelineMonth">
  <schedule:SfScheduler.ResourceView>
    <schedule:SchedulerResourceView>
       <schedule:SchedulerResourceView.Mapping>
          <schedule:SchedulerResourceMapping Name="Name"
                                             Id="Id"
                                             Background="Background"
                                             />
       </schedule:SchedulerResourceView.Mapping>
    </schedule:SchedulerResourceView>
  </schedule:SfScheduler.ResourceView>
 </schedule:SfScheduler>
```

### Adding resources to the Scheduler

To add the resources to the Scheduler, create custom resources or employees and bind them to the [Resources](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Resources "Resources property of .NET MAUI Scheduler") property of the [SchedulerResourceView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html "SchedulerResourceView Class of .NET MAUI Scheduler") class.

Refer to the following code.

```xml
this.Resources = this.GetSchedulerResources();
/// <summary>
/// Method to get resources or employees to the scheduler.
/// </summary>
/// <returns>Scheduler resources</returns>
private List<object> GetSchedulerResources()
{
     Random random = new();
     List<object> resources = new();
     List<string> employeeNames = new List<string>
     {
        "Robert", "Sophia", "Emilia" , "Stephen", "James William", "Johnny", "Daniel", "Adeline Ruby","Kinsley Elena",
     };

     for (int i = 0; i < 9; i++)
     {
         Employee employees = new();
         employees.Name = employeeNames[i];
         employees.Background = this.resourceColors[random.Next(this.resourceColors.Count)];
         employees.Id = i + 1;

         if (employees.Name == "Robert")
         {
            employees.ImageName = "people9.png";
            employees.Role = "Project manager";
         }
         else if (employees.Name == "Sophia")
         {
            employees.ImageName = "people2.png";
            employees.Role = "Team lead";
         }
         else if (employees.Name == "Emilia")
         {
            employees.ImageName = "people7.png";
            employees.Role = "Developer";
         }
         else if (employees.Name == "Stephen")
         {
             employees.ImageName = "people1.png";
             employees.Role = "Developer";
         }
         else if (employees.Name == "James William")
         {
             employees.ImageName = "people6.png";
             employees.Role = "Developer";
         }
         else if (employees.Name == "Daniel")
         {
             employees.ImageName = "people3.png";
             employees.Role = "Tester";
         }
         else if (employees.Name == "Johnny")
         {
             employees.ImageName = "people8.png";
             employees.Role = "Tester";
         }
         else if (employees.Name == "Adeline Ruby")
         {
              employees.ImageName = "people4.png";
              employees.Role = "Support Engineer";
         }
         else if (employees.Name == "Kinsley Elena")
         {
               employees.ImageName = "people5.png";
               employees.Role = "Content writer";
         }
         resources.Add(employees);
     }

     return resources;
}

<schedule:SfScheduler x:Name="Scheduler" View="TimelineMonth">
   <schedule:SfScheduler.ResourceView>
      <!--Bind custom Resources from view model-->
      <schedule:SchedulerResourceView Resources="{Binding Resources}">
         <schedule:SchedulerResourceView.Mapping>
           <schedule:SchedulerResourceMapping Name="Name"
                                              Id="Id"
                                              Background="Background"                      
                                              Foreground="Foreground"/>        
         </schedule:SchedulerResourceView.Mapping>
      </schedule:SchedulerResourceView>
   </schedule:SfScheduler.ResourceView>
   <schedule:SfScheduler.BindingContext>
      <local:ResourceViewModel/>
   </schedule:SfScheduler.BindingContext>

</schedule:SfScheduler>
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Add-resources-to-the-.NET-MAUI-Scheduler-1.png" alt="Add resources to the .NET MAUI Scheduler" style="width:100%">

  <figcaption>Add resources to the .NET MAUI Scheduler</figcaption>

</figure>
### Customizing the resource view appearance

You can also customize the resource view’s appearance using the [HeaderTemplate](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_HeaderTemplate "HeaderTemplate property of .NET MAUI Scheduler") property in the [SchedulerResourceView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html "SchedulerResourceView Class of .NET MAUI Scheduler") class.

Refer to the following code example to customize the resource view appearance.

```xml
<ContentPage.Resources>
     <local:ImageSourceConverter x:Key="imageConverter"/>
  </ContentPage.Resources>
  <schedule:SfScheduler x:Name="Scheduler" View="TimelineMonth">
     <schedule:SfScheduler.ResourceView>
       <schedule:SchedulerResourceView Resources="{Binding Resources}">
           <!--Customize the resource view appearance-->
           <schedule:SchedulerResourceView.HeaderTemplate>
              <DataTemplate>
                 <StackLayout Padding="5" Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="Fill">
                   <Border StrokeThickness="5"
                           Stroke="{Binding Background}"
                           HorizontalOptions="Center"
                           HeightRequest="{OnIdiom Desktop = 70, Phone = 65}"                                            
                           WidthRequest="{OnIdiom Desktop= 70, Phone=65}">
                     <Border.StrokeShape>
                         <RoundRectangle CornerRadius="150"/>
                     </Border.StrokeShape>
                     <Image WidthRequest="{OnIdiom Desktop = 55, Phone = 50}"                                               
                            HeightRequest="{OnIdiom Desktop = 55, Phone = 50}"
                            HorizontalOptions="Center"
                            Source="{Binding DataItem.ImageName,Converter={StaticResource imageConverter}}" 
                            VerticalOptions="Center"
                            Aspect="Fill"/>
                  </Border>
                  <Label Text="{Binding Name}" TextColor="Black" FontSize="{OnIdiom Desktop= 12, Phone=10}" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
               </StackLayout>
             </DataTemplate>
          </schedule:SchedulerResourceView.HeaderTemplate>                  
          <schedule:SchedulerResourceView.Mapping>
             <schedule:SchedulerResourceMapping Name="Name"
                                                Id="Id"                                                    
                                                Background="Background"
                                                Foreground="Foreground"/>                                       
         </schedule:SchedulerResourceView.Mapping>
       </schedule:SchedulerResourceView>
     </schedule:SfScheduler.ResourceView>
     <schedule:SfScheduler.BindingContext>
         <local:ResourceViewModel/>
     </schedule:SfScheduler.BindingContext>
</schedule:SfScheduler>

public class ImageSourceConverter : IValueConverter
{
   public object Convert(object? value, Type targetType, object parameter, CultureInfo culture)
   {
      return ImageSource.FromFile(value as string);
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Customize-the-.NET-MAUI-Scheduler-resource-view-appearance.png" alt="Customize the .NET MAUI Scheduler resource view appearance" style="width:100%">

  <figcaption>Customize the .NET MAUI Scheduler resource view appearance</figcaption>

</figure>
### Resource availability

You can manage and track the availability of resources by using the [special time region](https://help.syncfusion.com/maui/scheduler/timeline-views#special-time-regions "special time region in .NET MAUI Scheduler") or [blackout dates](https://help.syncfusion.com/maui/scheduler/date-navigation-restriction#selectable-day-predicate-blackout-dates "Blackout dates in .NET MAUI Scheduler") in timeline views.

The following code example adds **Saturday** and **Sunday** as blackout dates to avoid task planning during days off.

```csharp
scheduler.SelectableDayPredicate = (date) =>
{
   if (date.DayOfWeek == DayOfWeek.Sunday || date.DayOfWeek == DayOfWeek.Saturday)
   {
      return false;
    }
    return true;
};
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Plan-resource-availability-1.png" alt="Plan resource availability" style="width:100%">

  <figcaption>Plan resource availability</figcaption>

</figure>

## Scheduling tasks to the resources

Next, we are going to create tasks for employees by using the [AppointmentsSource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html#Syncfusion_Maui_Scheduler_SfScheduler_AppointmentsSource "AppointmentsSource property of .NET MAUI Scheduler") property.

### Creating employee Task model

Create a custom **Task** data model for an employee with the required fields **From** , **To** , and other optional fields.

```csharp
public class Task
{
        /// <summary>
        /// Gets or sets the value to display the start date.
        /// </summary>
        public DateTime From { get; set; }

        /// <summary>
        /// Gets or sets the value to display the end date.
        /// </summary>
        public DateTime To { get; set; }

        /// <summary>
        /// Gets or sets the value to display the subject.
        /// </summary>
        public string TaskName { get; set; }

        /// <summary>
        /// Gets or sets the value to display the background.
        /// </summary>
        public Brush Background { get; set; }

        /// <summary>
        /// Gets or sets the value to display the Rule.
        /// </summary>
        public string RecurrenceRule { get; set; }

        /// <summary>
        /// Gets or sets the value to display the resource collection.
        /// </summary>
        public ObservableCollection<object> Resources { get; set; }

        /// <summary>
        /// Gets or sets the value to an all-day appointment.
        /// </summary>
        public bool IsAllDay { get; set; }
 }
```

### Mapping the custom task module to the Scheduler

Then, map the custom employee **Task** data model properties to the [AppointmentMapping](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html#Syncfusion_Maui_Scheduler_SfScheduler_AppointmentMapping "AppointmentMapping property of .NET MAUI Scheduler") properties of the [SfScheduler](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html "SfScheduler Class of .NET MAUI Scheduler") class. You can create tasks for employees by using the [ResourceIds](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerAppointmentMapping.html#Syncfusion_Maui_Scheduler_SchedulerAppointmentMapping_ResourceIds "ResourceIds property of .NET MAUI Scheduler") property of the [SchedulerAppointmentMapping](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerAppointmentMapping.html "SchedulerAppointmentMapping Class of .NET MAUI Scheduler") class.

```xml
<schedule:SfScheduler x:Name="Scheduler"                            
                        AllowedViews="TimelineDay,TimelineWeek,TimelineWorkWeek,TimelineMonth"
                        View="TimelineMonth">
   <schedule:SfScheduler.AppointmentMapping>
      <schedule:SchedulerAppointmentMapping
                    Subject="TaskName"
                    StartTime="From"
                    EndTime="To"
                    IsAllDay="IsAllDay"
                    Background="Background"
                    RecurrenceRule="RecurrenceRule"
                    ResourceIds="Resources"/>
   </schedule:SfScheduler.AppointmentMapping>
 </schedule:SfScheduler>
```

### Create tasks for the employees

In the following, tasks are created for resources using the **Resources** of **Task** by assigning the **Id**  of the scheduler resources **.**

```csharp
this.Tasks = this.GetEmployeeTasks();
/// <summary>
/// Method to get tasks for employees.
/// </summary>
/// <returns>Employee tasks</returns>
private List<Task> GetEmployeeTasks()
{
            Random random = new();
            List<Task> tasks = new();
            DateTime dateFrom = DateTime.Now.AddDays(-80);
            DateTime dateTo = DateTime.Now.AddDays(80);

            List<string> managerTasks = new List<string> { "Project goal", "Project plan", "API review", "Project final review" };
            List<string> teamleadTasks = new List<string> { "Project requirments", "Project design", "API analysis", "Feature review", "Support coordinate", "Tech Blog", "Sprint plan", "Sprint review", "Sprint retrospect" };
            List<string> supportTasks = new List<string> { "Customer meeting", "User guide documentation", "Knowbase document" };
            List<string> developmentTasks = new List<string> { "Base for calendar", "Implement month calendar", "Implement year calendar", "Implement decade calendar", "Implement century calendar", "Implement date selection", "Implement range selection", "Implement blackout dates", "Implement multiple selection" };
            List<string> testingTasks = new List<string> { "Unit testing", "UI automation", "Performance testing", "Memory leak testing", "Feature testing", "Demos testing", "Automate test cases", "Peer testing", "Exploratory testing", "Sanity testing" };
            List<string> documentationTasks = new List<string> { "User guide documentation", "Feature tour", "Whats new", "Road map", "Knowledge base", "Technical review", "Content review", };
            for (DateTime date = dateFrom; date < dateTo; date = date.AddDays(1))
            {
                if (date.DayOfWeek != DayOfWeek.Monday)
                    continue;
                for (int i = 0; i < 9; i++)
                {
                    Employee resource = this.Resources[i] as Employee;
                    DateTime startDate = new DateTime(date.Year, date.Month, date.Day, random.Next(9, 18), 0, 0);
                    //// Create a task for an employee.
                    Task task = new();
                    task.From = startDate;
                    task.To = startDate.AddDays(4).AddHours(1);
                    task.Background = this.resourceColors[random.Next(resourceColors.Count)];
                    //// Assign tasks to the employees.
                    task.Resources = new ObservableCollection<object>() { resource.Id };
                    task.IsAllDay = true;
                    if (string.Equals(resource.Role, "Project manager"))
                    {
                        task.TaskName = managerTasks[random.Next(managerTasks.Count)];
                    }
                    else if (string.Equals(resource.Role, "Team lead"))
                    {
                        task.TaskName = teamleadTasks[random.Next(teamleadTasks.Count)];
                    }
                    else if (string.Equals(resource.Role, "Developer"))
                    {
                        task.TaskName = developmentTasks[random.Next(developmentTasks.Count)];
                    }
                    else if (string.Equals(resource.Role, "Tester"))
                    {
                        task.TaskName = testingTasks[random.Next(testingTasks.Count)];
                    }
                    else if (string.Equals(resource.Role, "Support Engineer"))
                    {
                        task.TaskName = supportTasks[random.Next(supportTasks.Count)];
                    }
                    else if (string.Equals(resource.Role, "Content writer"))
                    {
                        task.TaskName = documentationTasks[random.Next(documentationTasks.Count)];
                    }

                    tasks.Add(task); }
            }
            return tasks;
 }
```

### Bind the employee’s tasks to the Scheduler

Then, bind the employees’ tasks by using the [AppointmentsSource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html#Syncfusion_Maui_Scheduler_SfScheduler_AppointmentsSource "AppointmentsSource property of .NET MAUI Scheduler") property.

In the following code, the  **Tasks**  property binds to the AppointmentsSource property from the view model to plan the employee’s tasks.

```xml
<!--Bind custom Tasks from the view model to AppointmentsSource property-->
 <schedule:SfScheduler x:Name="Scheduler"
                         AppointmentsSource="{Binding Tasks}" AllowedViews="TimelineDay,TimelineWeek,TimelineWorkWeek,TimelineMonth"
                         View="TimelineMonth">
     <schedule:SfScheduler.AppointmentMapping>
       <schedule:SchedulerAppointmentMapping
                    Subject="TaskName"
                    StartTime="From"
                    EndTime="To"
                    IsAllDay="IsAllDay"
                    Background="Background"
                    RecurrenceRule="RecurrenceRule"
                    ResourceIds="Resources"/>
    </schedule:SfScheduler.AppointmentMapping>
    <schedule:SfScheduler.BindingContext>
        <local:ResourceViewModel/>
    </schedule:SfScheduler.BindingContext>
</schedule:SfScheduler>
```

## Sharing appointments with multiple resources

You can share the same event or common progress meetings with multiple resources to discuss the progress of the tasks by using multiresource sharing support.

Please refer to the following code example to create multiple-resource-sharing appointments by listing the required resource IDs for the appointments.

```csharp
//// Plan weekly development meeting.  
Task overAllDevelopmentMeeting = new();
overAllDevelopmentMeeting.TaskName = "Development meeting";
overAllDevelopmentMeeting.From = new DateTime(dateFrom.Year, dateFrom.Month, dateFrom.Day, 11, 30, 0);
overAllDevelopmentMeeting.To = overAllDevelopmentMeeting.From.AddMinutes(30);
overAllDevelopmentMeeting.Background = Color.FromArgb("#FF36B37B");
//// Same appointment will be shared with the multiresource.
overAllDevelopmentMeeting.Resources = new ObservableCollection<object>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
overAllDevelopmentMeeting.IsAllDay = false;
overAllDevelopmentMeeting.RecurrenceRule = "FREQ=WEEKLY;BYDAY=TU;INTERVAL=1";
tasks.Add(overAllDevelopmentMeeting);
```
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2023/01/Plan-task-to-resources-1.png" alt="Plan task to multiple resources" style="width:100%">

  <figcaption>Plan task to multiple resources</figcaption>

</figure>
## GitHub reference

For more information, you can download the complete example of the [project planning calendar for resource scheduling using the .NET MAUI Scheduler](https://github.com/SyncfusionExamples/project-planning-and-resource-management-calendar-using-the-maui-scheduler "Project planning calendar for resource scheduling using the .NET MAUI Scheduler GitHub demo").

## Conclusion

Thank you for reading! In this blog, we had a quick overview of how to create a project planning and resource management calendar using the Syncfusion [.NET MAUI Scheduler](https://www.syncfusion.com/maui-controls/maui-scheduler ".NET MAUI Scheduler").

Please let us know in the comments section below if you have any feedback, specific requirements, or controls that you’d like to see in our .NET MAUI suite.

You can also contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Sycfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/maui "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Syncfusion Essential Studio 2022 Volume 4 Is Here!](https://www.syncfusion.com/blogs/post/syncfusion-essential-studio-2022-volume-4-is-here.aspx "Blog: Syncfusion Essential Studio 2022 Volume 4 Is Here!")
- [Syncfusion .NET MAUI 2023 Roadmap](https://www.syncfusion.com/blogs/post/syncfusion-net-maui-2023-roadmap.aspx "Blog: Syncfusion .NET MAUI 2023 Roadmap")
- [Authenticate the .NET MAUI App with Azure AD](https://www.syncfusion.com/blogs/post/authenticate-the-net-maui-app-with-azure-ad.aspx "Blog: Authenticate the .NET MAUI App with Azure AD")
- [Introducing the Sixth Set of .NET MAUI Controls](https://www.syncfusion.com/blogs/post/introducing-the-sixth-set-of-net-maui-controls.aspx "Blog: Introducing the Sixth Set of .NET MAUI Controls")