Resource Grouping in WPF Scheduler (SfScheduler)
31 Mar 202224 minutes to read
The WPF Scheduler resource view will allow to group appointments based on the resources or dates, arranged by the column or row in the day, week, workweek, timeline day, timeline week, timeline workweek and timeline month views. It also allows to share the events or appointments to the multiple resources and resource appointment details can be edited by using a built-in appointment editor.
Grouping by Resources
Resources can be added to the scheduler by setting the ResourceGroupType property as Resource
in SfScheduler.
Set the Id, Name, Foreground and Background properties of SchedulerResource to create a resource. Add the resource to the scheduler by using the ResourceCollection property of SfScheduler
and also add or remove the scheduler resources dynamically.
NOTE
No resource view will be displayed, even a resource added using the
ResourceCollection
property when theResourceGroupType
property value is set toNone
.
// Adding schedule resource in the scheduler resource collection.
var ResourceCollection = new ObservableCollection<SchedulerResource>()
{
new SchedulerResource() { Name = "Sophia", Background = new SolidColorBrush(Colors.Red), Id = "1000" },
new SchedulerResource() { Name = "Zoey Addison", Background = new SolidColorBrush(Colors.Blue), Id = "1001" },
new SchedulerResource() { Name = "James William", Background = new SolidColorBrush(Colors.Yellow), Id = "1002" },
};
// Adding the scheduler resource collection to the schedule resources of SfSchedule.
schedule.ResourceCollection = ResourceCollection;
<syncfusion:SfScheduler x:Name="Schedule" ViewType="Week" ResourceGroupType="resource" ResourceCollection="{Binding ResourceCollection}">
NOTE
Resource Grouping types
Group the resource order by Date
or order by Resource
using the ResourceGroupType property of SfScheduler
.
NOTE
Group the resource order in the day, week, work week, timeline day, timeline week, timeline workweek and timeline month views.
Resource
The ResourceGroupType
is set to Resource
to group the number of dates under each resource.
<Schedule:SfScheduler Name="schedule" ViewType="Week" ResourceGroupType="Resource"/>
schedule.ViewType = SchedulerViewType.Week;
schedule.ResourceGroupType = ResourceGroupType.Resource;
Date
The ResourceGroupType
is set to Date
to group the number of resources under each date.
<Schedule:SfScheduler Name="schedule" ViewType="Week" ResourceGroupType="Date"/>
schedule.ViewType = SchedulerViewType.Week;
schedule.ResourceGroupType = ResourceGroupType.Date;
Assigning resources to appointments
Appointments associated with scheduler ResourceCollection
will be displayed when set schedule resource Id
in the ScheduleAppointment by using the ResourceIdCollection for ResourceGroupType
set as Resource
or Date
. Also assign the resources to recurrence appointments.
ScheduleAppointmentCollection scheduleAppointmentCollection = new ScheduleAppointmentCollection();
var appointments = new ScheduleAppointment()
{
StartTime = DateTime.Now.AddMinutes(20),
EndTime = DateTime.Now.AddHours(2),
Subject = "General Meeting",
ResourceIdCollection = new ObservableCollection<object> () { "1000", "1001" }
};
scheduleAppointmentCollection.Add(appointments);
this.schedule.ItemsSource = scheduleAppointmentCollection;
NOTE
• When
ResourceIdCollection
is not added to ‘ScheduleAppointment’ then the appointment will not be displayed in, whenResourceGroupType
is set asResource
orDate
.
• WhenResourceGroupType
is set asNone
, resource view will be collapsed and all scheduler DataSource events will be displayed.
• Also add or remove the appointment resources dynamically.
Multiple resource sharing
Multiple resources can share the same events or appointments. If the appointment details are edited or updated, then the changes will reflect on all other shared instances simultaneously.
ScheduleAppointmentCollection scheduleAppointmentCollection = new ScheduleAppointmentCollection();
var appointments = new ScheduleAppointment()
{
StartTime = new DateTime(2020, 10, 01, 10, 0, 0),
EndTime = new DateTime(2020, 10, 01, 12, 0, 0),
Subject = "Project Plan",
ResourceIdCollection = new ObservableCollection<object>() { "1000", "1001","1002" }
AppointmentBackground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFE671B8")),
};
scheduleAppointmentCollection.Add(appointments);
this.schedule.ItemsSource = scheduleAppointmentCollection;
Scheduler Resource Mapping
Schedule supports full data binding to ResourceCollection. Specify the ResourceMapping attribute to map the properties in the underlying data source to the schedule resource.
Property Name | Description |
---|---|
Name | Maps the property name of the custom class, which is equivalent to Name in the ScheduleResource. |
Id | Maps the property name of custom class, which is equivalent to Id in ScheduleResource. |
Background | Maps the property name of custom class, which is equivalent to Background in ScheduleResource. |
Foreground | Maps the property name of custom class, which is equivalent to Foreground in ScheduleResource. |
NOTE
Custom resource class should contain a mandatory field for resource
Id
.
Create business object for Resource
Create a custom class Employee
with mandatory fields Name
, Id
, ForegroundColor
and BackgroundColor
. Also assign the resources to recurrence appointments.
public class Employee
{
public string Name {get; set;}
public string Id {get; set;}
public Brush BackgroundColor {get; set; }
public Brush ForegroundColor {get; set; }
}
NOTE
• Inherit this class from
INotifyPropertyChanged
for dynamic changes in custom data.
• SchedulerResource.Data property is used to get the details of the custom data.
Map the properties of Employee
class with SfScheduler
control using Scheduler ResourceMapping
.
<Schedule:SfScheduler Name="schedule" ViewType="Week" ResourceGroupType="Resource">
<Schedule:SfScheduler.ResourceMapping>
<Schedule:ResourceMapping Id="Id" Name="Name" Background="BackgroundColor" Foreground="ForegroundColor"/>
</Schedule:SfScheduler.ResourceMapping>
</Schedule:SfScheduler>
// Schedule data mapping for custom resource.
ResourceMapping resourceMapping = new ResourceMapping();
resourceMapping.Name = "Name";
resourceMapping.Id = "Id";
resourceMapping.Background = "BackgroundColor";
resourceMapping.Foreground = "ForegroundColor";
schedule.ResourceMapping = resourceMapping;
Assign resource object collection
Add the resources of Employee
collection that can be assigned to the scheduler using the ResourceCollection
property which is of IEnumerable
type. Also add or remove scheduler resources dynamically.
// Creating and Adding custom resource in scheduler resource collection.
var ResourceCollection = new ObservableCollection<Employee>()
{
new Employee () {Name = "Sophia", BackgroundColor = new SolidColorBrush(Colors.Red), Id = "1000", ForegroundColor = new SolidColorBrush(Colors.White) },
new Employee () {Name = "Zoey Addison", BackgroundColor = new SolidColorBrush(Colors.Blue), Id = "1001" , ForegroundColor = new SolidColorBrush(Colors.Red)},
new Employee () {Name = "James William", BackgroundColor = new SolidColorBrush(Colors.Yellow), Id = "1002" , ForegroundColor = new SolidColorBrush(Colors.Yellow)},
};
//Adding schedule resource collection to schedule resources.
schedule.ResourceCollection = ResourceCollection;
Assign the resource objects to appointment business object
Associate scheduler ResourceMapping
to the custom appointment by mapping resource Id
in the ResourceIdCollection
property of AppointmentMapping. Custom appointments associated with the scheduler resources will be displayed when ResourceGroupType
set as Resource
or Date
. Also assign resources to recurrence appointments.
/// <summary>
/// Represents the custom data properties.
/// </summary>
public class Meeting
{
public string EventName {get; set;}
public DateTime From {get; set;}
public DateTime To {get; set;}
public ObservableCollection<object> Resources {get; set;}
}
NOTE
Inherit this class from the
INotifyPropertyChanged
for dynamic changes in custom data.
Map those properties of Meeting
class to schedule appointment by using AppointmentMapping
properties.
<syncfusion:SfScheduler x:Name="Schedule" ItemsSource="{Binding Appointments}" ViewType="Week">
<syncfusion:SfScheduler.AppointmentMapping>
<syncfusion:AppointmentMapping
Subject="EventName"
StartTime="From"
EndTime="To"
ResourceIdCollection ="Resources"/>
</syncfusion:SfScheduler.AppointmentMapping>
</syncfusion:SfScheduler>
//Schedule data mapping for custom appointments
AppointmentMapping dataMapping = new AppointmentMapping();
dataMapping.Subject = "EventName";
dataMapping.StartTime = "From";
dataMapping.EndTime = "To";
dataMapping.AppointmentBackground = "Color";
dataMapping.ResourceIdCollection= "Resources";
Schedule.AppointmentMapping = dataMapping;
Schedule meetings for a Resource by setting From
, To
and Resources
of Meeting class.
Meeting meeting = new Meeting ();
meeting.From = new DateTime(2020, 07, 01, 10, 0, 0);
meeting.To = meeting.From.AddHours(1);
meeting.EventName = "Meeting";
meeting.Resources = new ObservableCollection<object> { (Resources[0] as Employee).Id, (Resources[1] as Employee).Id };
var Meetings = new ObservableCollection<Meeting> ();
Meetings.Add(meeting);
schedule.ItemsSource = Meetings;
NOTE
Resource header size
Customize the resource header size in the day, week, workweek, timeline day, timeline week, timeline workweek and timeline month views by using the ResourceHeaderSize property of DaysViewSettings or TimelineViewSettings in SfScheduler
.
Resource header size in days view
DaysViewSettings
applicable for Day
, Week
and WorkWeek
views. By default, value of this property is set to 50.
<Schedule:SfScheduler Name="schedule" ViewType="Week" ResourceGroupType="Resource">
<Schedule:SfScheduler.DaysViewSettings>
<Schedule:DaysViewSettings ResourceHeaderSize="100"/>
</Schedule:SfScheduler.DaysViewSettings>
</Schedule:SfScheduler>
schedule.DaysViewSettings.ResourceHeaderSize = 100;
Resource header size in timeline view
TimelineViewSettings
applicable for timeline day, timeline week, timeline workweek and timeline month views. By default, value of this property is set to 50.
<Schedule:SfScheduler Name="schedule" ViewType="TimelineWeek" ResourceGroupType="Resource">
<Schedule:SfScheduler.TimelineViewSettings>
<Schedule:TimelineViewSettings ResourceHeaderSize="100"/>
</Schedule:SfScheduler.TimelineViewSettings>
</Schedule:SfScheduler>
schedule.TimelineViewSettings.ResourceHeaderSize = 80;
Resource auto height
The resource row height gets auto-adjusted based on the number of overlapping appointments occupied on the same time range by setting RowAutoHeight property as true
in TimelineViewSettings. By default, value of this property is set to false.
<Schedule:SfScheduler Name="schedule"
ViewType="TimelineWeek"
ResourceGroupType="Resource">
<Schedule:SfScheduler.TimelineViewSettings>
<Schedule:TimelineViewSettings RowAutoHeight="True" />
</Schedule:SfScheduler.TimelineViewSettings>
</Schedule:SfScheduler>
schedule.TimelineViewSettings.RowAutoHeight = true;
NOTE
NOTE
- This auto row height adjustment is applicable only on all the Timeline views such as timeline day, timeline week, timeline workweek and timeline month views.
- If auto resource row height is enabled then VisibleResourceCount will not be applicable and if resources have no appointments, then RowMinHeight will be considered as default resource row height.
Resource minimum height
You can customize the minimum row height of visible resources in timeline day, timeline week, timeline workweek and timeline month views by using the RowMinHeight property of TimelineViewSettings in SfScheduler. By default, value of this property is set to 50.
<Schedule:SfScheduler Name="schedule"
ViewType="TimelineWeek"
ResourceGroupType="Resource">
<Schedule:SfScheduler.TimelineViewSettings>
<Schedule:TimelineViewSettings RowMinHeight="100" />
</Schedule:SfScheduler.TimelineViewSettings>
</Schedule:SfScheduler>
schedule.TimelineViewSettings.RowMinHeight = 100;
NOTE
The minimum resource row height adjusted based on view port size and the VisibleResourceCount will not be applicable.
Visible resource count
Customize the number of visible resources in day, week, workweek, timeline day, timeline week, timeline workweek and timeline month views by using the VisibleResourceCount property of DaysViewSettings
or TimelineViewSettings
in SfScheduler
.
NOTE
Visible resource count exceed count of schedule
ResourceCollection
count then scheduleResourceCollection
count will be displayed.
Visible resource count in days view
DaysViewSettings
applicable for Day
, Week
and WorkWeek
views. By default, value of this property is set to 3.
<Schedule:SfScheduler Name="schedule" ViewType="Week" ResourceGroupType="Resource">
<Schedule:SfScheduler.DaysViewSettings>
<Schedule:DaysViewSettings VisibleResourceCount="2"/>
</Schedule:SfScheduler.DaysViewSettings>
</Schedule:SfScheduler>
schedule.DaysViewSettings.VisibleResourceCount = 2;
Visible resource count in timeline views
TimelineViewSettings
applicable for timeline day, timeline week, timeline workweek and timeline month views. By default, value of this property is set to 3.
<Schedule:SfScheduler Name="schedule" ViewType="TimelineDay" ResourceGroupType="Resource">
<Schedule:SfScheduler.TimelineViewSettings>
<Schedule:TimelineViewSettings VisibleResourceCount="2"/>
</Schedule:SfScheduler.TimelineViewSettings>
</Schedule:SfScheduler>
schedule.TimelineViewSettings.VisibleResourceCount = 2;
Assign resources to special time regions
Special time region can be created based on the resources in day, week, workweek, timeline day, timeline week, timeline workweek and timeline month views.
Assign resources to special time regions in days view
Schedule.DaysViewSettings.SpecialTimeRegions.Add(new SpecialTimeRegion
{
StartTime = new System.DateTime(2020, 12, 13, 13, 0, 0),
EndTime = new System.DateTime(2020, 12, 13, 14, 0, 0),
Text = "Lunch",
CanEdit = false,
Background = Brushes.Black,
Foreground = Brushes.White,
RecurrenceRule = "FREQ=DAILY;INTERVAL=1",
CanMergeAdjacentRegions =false,
ResourceIdCollection = new ObservableCollection<object>() { "0", "1", "2" }
});
The SpecialTimeRegion in a Time basis by setting the value of CanMergeAdjacentRegions to True.
Assign resources to special time regions in timeline view
this.schedule.TimelineViewSettings.SpecialTimeRegions.Add(new SpecialTimeRegion
{
StartTime = new System.DateTime(2020, 09, 27, 1, 0, 0),
EndTime = new System.DateTime(2020, 09, 27, 2, 0, 0),
Text = "Lunch",
CanEdit = false,
Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#D3D3D3"),
Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#000000"),
RecurrenceRule = "FREQ=DAILY;INTERVAL=1",
ResourceIdCollection = new ObservableCollection<object>() { "1001", "1002", "1003" }
});
NOTE
Appearance customization
Resource UI customization using a template and template selectors support.
Customize resource appearance using ResourceHeaderTemplate
<Window.Resources>
<DataTemplate x:Key="DayViewResourceTemplate">
<Grid Background="Transparent">
<Border BorderThickness="0.3,0.3,0,0.3" BorderBrush="Gray" >
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<Border CornerRadius="36" Height="72" Width="72" BorderThickness="4" BorderBrush="{Binding Data.BackgroundBrush}">
<Border CornerRadius="36" Height="64" Width="64" BorderThickness="4" BorderBrush="White">
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="55"
Height="55" Source="{Binding Data.ImageSource}" />
</Border>
</Border>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15"
Foreground="Black" Text="{Binding Data.Name}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</Window.Resources>
//used to find Image Source and Name properties
<Window.DataContext>
<local:Employee />
</Window.DataContext>
<Grid Name="grid">
<syncfusion:SfScheduler x:Name="Schedule" ViewType="Week" ResourceGroupType="Resource" ResourceCollection="{Binding ResourceCollection}"
ResourceHeaderTemplate="{StaticResource DayViewResourceTemplate}">
<syncfusion:SfScheduler.ResourceMapping>
<syncfusion:ResourceMapping Id="Id" Name="Name" Background="BackgroundBrush" Foreground="ForegroundBrush"/>
</syncfusion:SfScheduler.ResourceMapping>
</syncfusion:SfScheduler>
</Grid>
Note
• By default, theSchedulerResource
is set as theDataContext
for theResourceHeaderTemplate
for bothSchedulerResource
and custom data object in theResourceCollection
.
• The custom data object can be bound in theResourceHeaderTemplate
by using the property of SchedulerResource.Data.
NOTE
Customize resource appearance using ResourceHeaderTemplateSelector
<Window.Resources>
<DataTemplate x:Key="DayViewResourceTemplate">
<Grid Background="Transparent">
<Border BorderThickness="0.3,0.3,0,0.3" BorderBrush="Gray" >
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<Border CornerRadius="36" Height="72" Width="72" BorderThickness="4" BorderBrush="{Binding Data.BackgroundBrush}">
<Border CornerRadius="36" Height="64" Width="64" BorderThickness="4" BorderBrush="White">
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="55"
Height="55" Source="{Binding Data.ImageSource}" />
</Border>
</Border>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15"
Foreground="Black" Text="{Binding Data.Name}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
<DataTemplate x:Key="TimelineViewResourceTemplate">
<Grid Background="Transparent">
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<Border CornerRadius="36" Height="72" Width="72" BorderThickness="4" BorderBrush="{Binding Data.BackgroundBrush}">
<Border CornerRadius="36" Height="64" Width="64" BorderThickness="4" BorderBrush="Transparent">
<Image HorizontalAlignment="Center" VerticalAlignment="Center"
Width="55"
Height="55"
Source="{Binding Data.ImageSource}" />
</Border>
</Border>
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="15"
Text="{Binding Data.Name}"/>
</StackPanel>
</Grid>
</DataTemplate>
<Window.Resources>
<Grid>
<Grid.DataContext>
<local:BindingViewModel/>
</Grid.DataContext>
<Grid.Resources>
<local:ResourceTemplateSelector x:Key="resourceTemplateSelector" DayViewResourceTemplate="{StaticResource DaysViewResourceTemplate}" TimelineViewResourceTemplate="{StaticResource TimelineResourceTemplate}"/>
</Grid.Resources>
<syncfusion:SfScheduler x:Name="Schedule"
ViewType="Week"
ResourceGroupType="Resource}"
ResourceCollection="{Binding Resources}"
ItemsSource="{Binding ResourceAppointments}" HeaderHeight="32"
DisplayDate="{Binding DisplayDate}" ResourceHeaderTemplateSelector="{StaticResource resourceTemplateSelector}">
</Grid>
Creating a ResourceHeaderTemplateSelector
public class ResourceTemplateSelector : DataTemplateSelector
{
/// <summary>
/// Initializes a new instance of the <see cref="ResourceTemplateSelector" /> class.
/// </summary>
public ResourceTemplateSelector()
{
}
public DataTemplate DayViewResourceTemplate {get; set;}
public DataTemplate TimelineViewResourceTemplate {get; set;}
/// <summary>
/// Template selection method
/// </summary>
/// <param name="item">return the object</param>
/// <param name="container">return the bindable object</param>
/// <returns>return the template</returns>
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var schedule = Syncfusion.Windows.Shared.VisualUtils.FindVisualParent<SfScheduler>(container);
if (schedule == null)
return null;
if (schedule.ViewType == SchedulerViewType.Day || schedule.ViewType == SchedulerViewType.Week || schedule.ViewType == SchedulerViewType.WorkWeek)
return DayViewResourceTemplate;
else
return TimelineViewResourceTemplate;
}
}
Note
• By default, theSchedulerResource
is set as theDataContext
for theResourceHeaderTemplateSelector
for bothSchedulerResource
and custom data object in theResourceCollection
.
• The custom data object can be bound in theResourceHeaderTemplateSelector
by using the property of SchedulerResource.Data.
NOTE