blazor-404769-components-scheduler-resources.md
You can assign one or multiple resources to Scheduler appointments to group appointments by category (display side-by-side calendars in a single control). For instance, if employees are resources, the Scheduler component allows users to browse appointments related to each employee.
Run Demo: Scheduler - Resources
Follow the steps below to add and assign resources to Scheduler appointments:
ResourceObject).ResourceObject class instances) and define their options:Color property value overrides the background color specified in the CSS class.SchedulerGroupType.Resource.<DxScheduler StartDate="@DateTime.Today"
DataStorage="@DataStorage"
GroupType="SchedulerGroupType.Resource"
ResourceColorInHeaderVisible="true">
<Views>
<DxSchedulerDayView DayCount="3"
TimeScale="@(new TimeSpan(1,0,0))"
WorkTime="new DxSchedulerTimeSpanRange(TimeSpan.FromHours(9), TimeSpan.FromHours(18))"
VisibleTime="new DxSchedulerTimeSpanRange(TimeSpan.FromHours(8), TimeSpan.FromHours(19))"
TimeIndicatorVisibility="SchedulerTimeIndicatorVisibility.Never">
</DxSchedulerDayView>
<DxSchedulerWeekView ShowWorkTimeOnly="true" />
<DxSchedulerWorkWeekView ShowWorkTimeOnly="true" />
<DxSchedulerTimelineView />
</Views>
</DxScheduler>
@code {
DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
AppointmentsSource = AppointmentCollection.GetAppointments(),
AppointmentMappings = new DxSchedulerAppointmentMappings() {
Type = "AppointmentType",
Start = "StartDate",
End = "EndDate",
Subject = "Caption",
AllDay = "AllDay",
Location = "Location",
Description = "Description",
LabelId = "Label",
StatusId = "Status",
RecurrenceInfo = "Recurrence",
ResourceId = "ResourceId"
},
ResourcesSource = ResourceCollection.GetResources(),
ResourceMappings = new DxSchedulerResourceMappings() {
Id = "Id",
Caption = "Name",
Color = "Color",
BackgroundCssClass = "BackgroundCss",
TextCssClass = "TextCss"
}
};
}
public class Appointment {
public Appointment() { }
public int AppointmentType { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public int? Label { get; set; }
public int Status { get; set; }
public bool AllDay { get; set; }
public string Recurrence { get; set; }
public int? ResourceId { get; set; }
}
public static partial class AppointmentCollection {
public static List<Appointment> GetAppointments() {
DateTime date = DateTime.Now.Date;
var dataSource = new List<Appointment>() {
new Appointment {
Caption = "Install New Router in Dev Room",
StartDate = date + (new TimeSpan(0, 10, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
Status = 1,
ResourceId = 0
},
new Appointment {
Caption = "Upgrade Personal Computers",
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 14, 30, 0)),
Status = 1,
ResourceId = 0
},
// ...
new Appointment {
Caption = "Final Budget Review",
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 15, 0, 0)),
Status = 1,
ResourceId = 1
},
new Appointment {
Caption = "Install New Database",
StartDate = date + (new TimeSpan(0, 9, 45, 0)),
EndDate = date + (new TimeSpan(1, 11, 15, 0)),
Status = 1,
ResourceId = 1
},
// ...
};
return dataSource;
}
}
public class ResourceObject {
public int Id { get; set; }
public string Name { get; set; }
public System.Drawing.Color Color { get; set; }
public string TextCss { get; set; }
public string BackgroundCss { get; set; }
}
public static partial class ResourceCollection {
public static List<ResourceObject> GetResources() {
var dataSource = new List<ResourceObject>() {
new ResourceObject() { Id=0 , Name="John Heart", TextCss="text-white",
BackgroundCss="dxbl-green-color",
/*Color = System.Drawing.Color.Green*/ },
new ResourceObject() { Id=1 , Name="Samantha Bright", TextCss="text-white",
BackgroundCss="dxbl-orange-color",
/*Color = System.Drawing.Color.Orange*/ },
new ResourceObject() { Id=2 , Name="Arthur Miller", TextCss="text-white",
BackgroundCss="dxbl-purple-color",
/*Color = System.Drawing.Color.Purple*/ },
};
return dataSource;
}
}
Resources allow you to display schedules across multiple columns. To group appointments by resources, set the GroupType property to Resource.
Run Demo: Scheduler Resources - Group by Resource
You can also set the GroupType property to Date. In this case, the Scheduler component displays multiple dates and resources, resource headers are grouped under date headers.
Run Demo: Scheduler Resources - Group by Date
The DevExpress Blazor Scheduler component includes a drop-down Resource Navigator window. Use this window to hide or display resource groups.
Use the ResourceNavigatorVisible property to specify whether the Resource Navigator is visible. The following code snippet replaces the build-in Resource Navigator with a custom tree-like navigator.
<div>
<div>
<div>
<DxButton RenderStyle="ButtonRenderStyle.None" Click="@ToggleResourceNavigator" IconCssClass="demo-resnavigator-icon" title="Toggle the resource navigator" />
@if(ResourceNavigatorExpanded) {
<span>Resources</span>
}
</div>
@if(ResourceNavigatorExpanded) {
<div>
<DxTreeView AfterCollapse="@(e => UpdateExpandedState(e, false))" AfterExpand="@(e => UpdateExpandedState(e, true))">
<Nodes>
@foreach(Resource group in Groups) {
<DxTreeViewNode Text="@group.Name" Name="@group.Id.ToString()" Expanded="@IsExpanded(group)">
<Nodes>
@foreach(Resource resource in GetResources(group)) {
<DxTreeViewNode Text="@resource.Name">
<Template>
<DxCheckBox T="bool"
Checked="@IsVisible(resource)"
CheckedChanged="@(visible => UpdateVisibilty(resource, visible))">
@resource.Name
</DxCheckBox>
</Template>
</DxTreeViewNode>
}
</Nodes>
</DxTreeViewNode>
}
</Nodes>
</DxTreeView>
</div>
}
</div>
<div>
<DxScheduler @bind-StartDate="@StartDate"
DataStorage="@DataStorage"
VisibleResourcesDataSource="@VisibleResources"
GroupType="SchedulerGroupType.Resource"
ResourceNavigatorVisible="false">
<DxSchedulerDayView DayCount="1" ShowWorkTimeOnly="true"></DxSchedulerDayView>
</DxScheduler>
</div>
</div>
@code {
List<Resource> Groups = ResourceCollection.GetResourceGroups();
List<Resource> VisibleResources = ResourceCollection.GetResources().Take(2).ToList();
bool ResourceNavigatorExpanded { get; set; } = true;
DateTime StartDate = DateTime.Today;
DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
AppointmentsSource = ResourceAppointmentCollection.GetAppointments(),
AppointmentMappings = new DxSchedulerAppointmentMappings() {
Type = "AppointmentType",
Start = "StartDate",
End = "EndDate",
Subject = "Caption",
AllDay = "AllDay",
Location = "Location",
Description = "Description",
LabelId = "Label",
StatusId = "Status",
RecurrenceInfo = "Recurrence",
ResourceId = "ResourceId"
},
ResourcesSource = ResourceCollection.GetResources(),
ResourceMappings = new DxSchedulerResourceMappings() {
Id = "Id",
Caption = "Name",
BackgroundCssClass = "BackgroundCss",
TextCssClass = "TextCss"
}
};
Dictionary<int, bool> ExpandedState = new Dictionary<int, bool>();
bool IsVisible(Resource resource) {
return VisibleResources.Contains(resource);
}
void UpdateVisibilty(Resource resource, bool visible) {
if(visible)
VisibleResources.Add(resource);
else
VisibleResources.Remove(resource);
VisibleResources = VisibleResources.OrderBy(p => p.Id).ToList();
}
bool IsExpanded(Resource resource) {
return ExpandedState.ContainsKey(resource.Id) ? ExpandedState[resource.Id] : true;
}
void UpdateExpandedState(TreeViewNodeEventArgs args, bool expanded) {
int resourceId = int.Parse(args.NodeInfo.Name);
ExpandedState[resourceId] = expanded;
}
void ToggleResourceNavigator() {
ResourceNavigatorExpanded = !ResourceNavigatorExpanded;
}
IEnumerable<Resource> GetResources(Resource group) {
return ResourceCollection.GetResources()
.Where(resource => resource.GroupId == group.Id);
}
}
public class Appointment {
public Appointment() { }
public int AppointmentType { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public int? Label { get; set; }
public int Status { get; set; }
public bool AllDay { get; set; }
public string Recurrence { get; set; }
public int? ResourceId { get; set; }
public string Resources { get; set; }
public bool Accepted { get; set; }
}
public static partial class ResourceAppointmentCollection {
public static List<Appointment> GetAppointments() {
DateTime date = DateTime.Now.Date;
var dataSource = new List<Appointment>() {
new Appointment {
Accepted = true,
Caption = "Install New Router in Dev Room",
StartDate = date + (new TimeSpan(0, 10, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
Status = 1,
ResourceId = 0
},
new Appointment {
Caption = "Upgrade Personal Computers",
Accepted = false,
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 14, 30, 0)),
Status = 2,
ResourceId = 0
},
new Appointment {
Caption = "Website Redesign Plan",
Accepted = false,
StartDate = date + (new TimeSpan(1, 9, 30, 0)),
EndDate = date + (new TimeSpan(1, 11, 30, 0)),
Status = 3,
ResourceId = 0
},
new Appointment {
Caption = "New Brochures",
Accepted = true,
StartDate = date + (new TimeSpan(1, 13, 30, 0)),
EndDate = date + (new TimeSpan(1, 15, 15, 0)),
Status = 4,
ResourceId = 0
},
new Appointment {
Caption = "Book Flights to San Fran for Sales Trip",
Accepted = false,
StartDate = date + (new TimeSpan(1, 12, 0, 0)),
EndDate = date + (new TimeSpan(1, 13, 0, 0)),
AllDay = true,
Status = 1,
ResourceId = 0
},
new Appointment {
Caption = "Approve Personal Computer Upgrade Plan",
Accepted = true,
StartDate = date + (new TimeSpan(0, 10, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
Status = 2
},
new Appointment {
Caption = "Final Budget Review",
Accepted = true,
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 15, 0, 0)),
Status = 3,
ResourceId = 1
},
new Appointment {
Caption = "Install New Database",
Accepted = false,
StartDate = date + (new TimeSpan(0, 9, 45, 0)),
EndDate = date + (new TimeSpan(1, 11, 15, 0)),
Status = 4,
ResourceId = 1
},
new Appointment {
Accepted = true,
Caption = "Approve New Online Marketing Strategy",
StartDate = date + (new TimeSpan(1, 12, 0, 0)),
EndDate = date + (new TimeSpan(1, 14, 0, 0)),
Status = 1,
ResourceId = 1
},
new Appointment {
Accepted = true,
Caption = "Customer Workshop",
StartDate = date + (new TimeSpan(0, 11, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
AllDay = true,
Status = 2,
ResourceId = 2
},
new Appointment {
Accepted = true,
Caption = "Prepare 2021 Marketing Plan",
StartDate = date + (new TimeSpan(0, 11, 0, 0)),
EndDate = date + (new TimeSpan(0, 13, 30, 0)),
Status = 3,
ResourceId = 2
},
new Appointment {
Accepted = false,
Caption = "Brochure Design Review",
StartDate = date + (new TimeSpan(0, 14, 0, 0)),
EndDate = date + (new TimeSpan(0, 15, 30, 0)),
Status = 4,
ResourceId = 2
},
new Appointment {
Accepted = true,
Caption = "Create Icons for Website",
StartDate = date + (new TimeSpan(1, 10, 0, 0)),
EndDate = date + (new TimeSpan(1, 11, 30, 0)),
Status = 1,
ResourceId = 1
},
new Appointment {
Accepted = true,
Caption = "Launch New Website",
StartDate = date + (new TimeSpan(1, 12, 20, 0)),
EndDate = date + (new TimeSpan(1, 14, 0, 0)),
Status = 1,
ResourceId = 2
},
new Appointment {
Accepted = false,
Caption = "Upgrade Server Hardware",
StartDate = date + (new TimeSpan(1, 9, 0, 0)),
EndDate = date + (new TimeSpan(1, 12, 0, 0)),
Status = 2,
ResourceId = 2
},
new Appointment {
Accepted = true,
Caption = "Book Flights to San Fran for Sales Trip",
StartDate = date + (new TimeSpan(0, 14, 0, 0)),
EndDate = date + (new TimeSpan(0, 17, 0, 0)),
Status = 1,
ResourceId = 3
},
new Appointment {
Accepted = true,
Caption = "Approve New Online Marketing Strategy",
StartDate = date + (new TimeSpan(0, 12, 0, 0)),
EndDate = date + (new TimeSpan(0, 15, 0, 0)),
Status = 3,
ResourceId = 4
}
};
return dataSource;
}
}
public class Resource {
public int Id { get; set; }
public int? GroupId { get; set; }
public string Name { get; set; }
public bool IsGroup { get; set; }
public string TextCss { get; set; }
public string BackgroundCss { get; set; }
public override bool Equals(object obj) {
Resource resource = obj as Resource;
return resource != null && resource.Id == Id;
}
public override int GetHashCode() {
return Id;
}
}
}
public static partial class ResourceCollection {
public static List<Resource> GetResourcesForGrouping() {
return GetResources().Take(3).ToList();
}
public static List<Resource> GetResources() {
return new List<Resource>() {
new Resource() { Id=0 , Name="Nancy Davolio", GroupId=100, BackgroundCss="dxbl-green-color", TextCss="dxbl-white-font-color" },
new Resource() { Id=1 , Name="Andrew Fuller", GroupId=101, BackgroundCss="dxbl-orange-color", TextCss="dxbl-white-font-color" },
new Resource() { Id=2 , Name="Janet Leverling", GroupId=100, BackgroundCss="dxbl-purple-color", TextCss="dxbl-white-font-color" },
new Resource() { Id=3 , Name="Margaret Peacock", GroupId=101, BackgroundCss="dxbl-indigo-color", TextCss="dxbl-white-font-color" },
new Resource() { Id=4 , Name="Steven Buchanan", GroupId=100, BackgroundCss="dxbl-red-color", TextCss="dxbl-white-font-color" }
};
}
public static List<Resource> GetResourceGroups() {
return new List<Resource>() {
new Resource() { Id=100, Name="Sales and Marketing", IsGroup=true },
new Resource() { Id=101, Name="Engineering", IsGroup=true }
};
}
}
Run Demo: Scheduler - Custom Resource Navigator
The DevExpress Blazor Scheduler component allows you to assign multiple resources to an appointment. This feature is useful for the following cases: meetings with multiple participants, group events, or services that require coordination among various resources.
Follow the steps below to enable this functionality:
Set the EnableMultipleResources property to ‘true’.
Add a new data field (Resources) to an appointment’s source object.
Map this field to the ResourceId appointment property.
Show Complete Code
<DxScheduler @bind-StartDate="@StartDate"
DataStorage="@DataStorage"
GroupType="SchedulerGroupType.Resource"
CssClass="demo-sc-size"
AppointmentFormMode="SchedulerAppointmentFormMode.EditForm">
<DxSchedulerDayView DayCount="2" ShowWorkTimeOnly="true"></DxSchedulerDayView>
</DxScheduler>
@code {
DateTime StartDate { get; set; } = DateTime.Today;
DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
AppointmentsSource = MultipleResourceAppointmentCollection.GetAppointments(),
AppointmentMappings = new DxSchedulerAppointmentMappings() {
Type = "AppointmentType",
Start = "StartDate",
End = "EndDate",
Subject = "Caption",
AllDay = "AllDay",
Location = "Location",
Description = "Description",
LabelId = "Label",
StatusId = "Status",
RecurrenceInfo = "Recurrence",
ResourceId = "Resources"
},
ResourcesSource = ResourceCollection.GetResources(),
ResourceMappings = new DxSchedulerResourceMappings() {
Id = "Id",
Caption = "Name",
BackgroundCssClass = "BackgroundCss",
TextCssClass = "TextCss"
},
EnableMultipleResources = true
};
}
public class Appointment {
public Appointment() { }
public int AppointmentType { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public int? Label { get; set; }
public int Status { get; set; }
public bool AllDay { get; set; }
public string Recurrence { get; set; }
public int? ResourceId { get; set; }
public string Resources { get; set; }
public bool Accepted { get; set; }
}
public static partial class MultipleResourceAppointmentCollection {
public static List<Appointment> GetAppointments() {
DateTime date = DateTime.Now.Date;
return new List<Appointment>() {
new Appointment {
Accepted = true,
Caption = "Install New Router in Dev Room",
StartDate = date + (new TimeSpan(0, 10, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
Status = 1,
Resources = DxSchedulerResourceIdCollection.ToXml(0)
},
new Appointment {
Caption = "Upgrade Personal Computers",
Accepted = false,
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 14, 30, 0)),
Status = 2,
Resources = DxSchedulerResourceIdCollection.ToXml(0, 1)
},
new Appointment {
Caption = "Website Redesign Plan",
Accepted = false,
StartDate = date + (new TimeSpan(1, 9, 30, 0)),
EndDate = date + (new TimeSpan(1, 11, 30, 0)),
Status = 3,
Resources = DxSchedulerResourceIdCollection.ToXml(0, 1, 2)
},
new Appointment {
Caption = "Approve Personal Computer Upgrade Plan",
Accepted = true,
StartDate = date + (new TimeSpan(0, 14, 0, 0)),
EndDate = date + (new TimeSpan(0, 16, 0, 0)),
Status = 2,
Resources = DxSchedulerResourceIdCollection.ToXml(2, 3, 4)
},
};
}
}
public class Resource {
public int Id { get; set; }
public int? GroupId { get; set; }
public string Name { get; set; }
public bool IsGroup { get; set; }
public string TextCss { get; set; }
public string BackgroundCss { get; set; }
public string ImageFileName => $"employees/{Id + 1}.jpg";
public override bool Equals(object obj) {
Resource resource = obj as Resource;
return resource != null && resource.Id == Id;
}
public override int GetHashCode() {
return Id;
}
}
public static partial class ResourceCollection {
public static List<Resource> GetResourcesForGrouping() {
return GetResources().Take(3).ToList();
}
public static List<Resource> GetResources() {
return new List<Resource>() {
new Resource() { Id=0 , Name="Nancy Davolio", GroupId=100, BackgroundCss="dxbl-green-color", TextCss="text-white" },
new Resource() { Id=1 , Name="Andrew Fuller", GroupId=101, BackgroundCss="dxbl-orange-color", TextCss="text-white" },
new Resource() { Id=2 , Name="Janet Leverling", GroupId=100, BackgroundCss="dxbl-purple-color", TextCss="text-white" },
new Resource() { Id=3 , Name="Margaret Peacock", GroupId=101, BackgroundCss="dxbl-indigo-color", TextCss="text-white" },
new Resource() { Id=4 , Name="Steven Buchanan", GroupId=100, BackgroundCss="dxbl-red-color", TextCss="text-white" }
};
}
public static List<Resource> GetResourceGroups() {
return new List<Resource>() {
new Resource() { Id=100, Name="Sales and Marketing", IsGroup=true },
new Resource() { Id=101, Name="Engineering", IsGroup=true }
};
}
}
Users can specify multiple resources in the Appointment edit form.
If you group appointments by resource, multi-resource appointments appear under all linked resources.
Run Demo: Scheduler Resources - Multiple Resources
The table below lists API members related to resources:
|
Member
|
Description
| | --- | --- | |
|
Creates a new resource item.
| |
|
Returns a resource item with the specified identifier from the Scheduler’s data storage.
| |
|
Specifies how Scheduler appointments are grouped. None, resource, date.
| |
|
Specifies whether a resource color is applied to the corresponding group’s header.
| |
|
Specifies whether the Scheduler displays the Resource Navigator.
| |
|
Specifies the data source that stores visible resource objects.
| |
DxSchedulerMonthView.ResourceCaptionOrientation
DxSchedulerTimelineView.ResourceCaptionOrientation
|
Arranges resource captions horizontally or vertically when appointments are grouped by date.
| |
DxSchedulerMonthView.VerticalResourceCellWidth
DxSchedulerTimelineView.VerticalResourceCellWidth
|
Specifies the resource cell width when appointments are grouped by date and resource captions are aligned horizontally.
|