Special and Restricted Slots
With R3 2019 release of Telerik UI for Xamarin RadCalendar provides the option to define a collection of special and restricted time slots in order to make them noticeable across the timeline of the Day and MultiDay views.
You just need to prepare a collection of SpecialSlot objects and assign it to SpecialSlotsSource collection of the DayViewSettings / MultiDayViewSettings for Day/MultiDay view, respectively.
Every SpecialSlot has the following properties:
- StartDate;
- EndDate;
- RecurrencePattern: Defines whether the slot will be displayed for repeating days;
- IsReadOnly: When set to True the slot is disabled (restricted), meaning the end user wouldn't be able to create or modify appointments at that slot (tapping over a read-only slot will not show Create Appointment screen).
Appointments that cover restricted and non restricted slots at the same time can still be modified through the Scheduling UIs.
Below you can find a quick example how to create special and restricted slots.
First, create a ViewModel class with a collection of SpecialSlot objects. In the example two repeating special slots are added for rest hours during weekdays. In addition, the first slot which represents a lunch break, is set as restricted time.
public class ViewModel
{
public ViewModel()
{
this.RestHours = new ObservableCollection<SpecialSlot>();
var today = DateTime.Today;
var dailyRecurrence = new RecurrencePattern()
{
DaysOfWeekMask = RecurrenceDays.WeekDays,
Frequency = RecurrenceFrequency.Weekly,
MaxOccurrences = 30
};
this.RestHours.Add(new SpecialSlot(today.AddHours(12), today.AddHours(13))
{
RecurrencePattern = dailyRecurrence,
IsReadOnly = true
});
this.RestHours.Add(new SpecialSlot(today.AddHours(16), today.AddHours(16).AddMinutes(15))
{
RecurrencePattern = dailyRecurrence
});
}
public ObservableCollection<SpecialSlot> RestHours { get; set; }
}
Then, add RadCalendar definition with MultiDay ViewMode and MultiDayViewSettings applied:
<telerikInput:RadCalendar x:Name="calendar"
ViewMode="MultiDay"
SchedulingUiEnabled="True">
<telerikInput:RadCalendar.MultiDayViewSettings>
<telerikInput:MultiDayViewSettings VisibleDays="7"
SpecialSlotsSource="{Binding RestHours}" />
</telerikInput:RadCalendar.MultiDayViewSettings>
</telerikInput:RadCalendar>
Last step is to set the BindingContext to the ViewModel class:
this.BindingContext = new ViewModel();
Here is the result after executing the example above on different platforms:
Setting a separate Style for different slots
Through the SpecialSlotStyleSelector property of the DayViewSettings (or MultiDayViewSettings) you can apply different background color to slots depending on certain condition. The SpecialSlotStyleSelector provides SelectStyle method with the SpecialSlot as a parameter. The method should return an object of type CalendarSpecialSlotStyle which exposes a BackgroundColor property.
The sample below extends the previous example by applying separate styles to both types of special slots through a SpecialSlotStyleSelector.
Create a custom style selector class which inherits from SpecialSlotStyleSelector and override SelectStyle method:
public class RestHoursStyleSelector : SpecialSlotStyleSelector
{
public CalendarSpecialSlotStyle LunchBreakStyle { get; set; }
public CalendarSpecialSlotStyle ShortBreakStyle { get; set; }
public override CalendarSpecialSlotStyle SelectStyle(object item)
{
var specialSlot = item as SpecialSlot;
if (specialSlot.StartDate.Hour == 12)
return this.LunchBreakStyle;
return this.ShortBreakStyle;
}
}
Add the created RestHoursStyleSelector as a Resource and define both Styles:
<ResourceDictionary>
<local:RestHoursStyleSelector x:Key="RestHoursStyleSelector">
<local:RestHoursStyleSelector.LunchBreakStyle>
<telerikInput:CalendarSpecialSlotStyle BackgroundColor="#FFD09E"/>
</local:RestHoursStyleSelector.LunchBreakStyle>
<local:RestHoursStyleSelector.ShortBreakStyle>
<telerikInput:CalendarSpecialSlotStyle BackgroundColor="#FFEAC6"/>
</local:RestHoursStyleSelector.ShortBreakStyle>
</local:RestHoursStyleSelector>
</ResourceDictionary>
All that is left, is to set the SpecialStyleSelector property of the MultiDayViewSettings:
<telerikInput:RadCalendar x:Name="calendar"
ViewMode="MultiDay"
SchedulingUiEnabled="True">
<telerikInput:RadCalendar.MultiDayViewSettings>
<telerikInput:MultiDayViewSettings VisibleDays="7"
SpecialSlotsSource="{Binding RestHours}"
SpecialSlotStyleSelector="{StaticResource RestHoursStyleSelector}"/>
</telerikInput:RadCalendar.MultiDayViewSettings>
</telerikInput:RadCalendar>
Check the result in the image below:
Applying a ContentTemplate to the slots
By default the special slots are marked with a different background. In addition you could show a content of your choice inside special slots through the SpecialSlotContentTemplate property of the DayViewSettings / MultiDaySettings.
For the example, create a custom slot that inherits from SpecialSlot class:
public class BreakSlot : SpecialSlot
{
private string title;
public string Title
{
get
{
return this.title;
}
set
{
if (this.title != value)
{
this.title = value;
this.OnPropertyChanged();
}
}
}
}
In the ViewModel class, add a collection of BreakSlot objects that will be then assigned as a SpecialSlotsSource:
public class ViewModel
{
public ViewModel()
{
this.RestHours = new ObservableCollection<BreakSlot>();
var today = DateTime.Today;
var dailyRecurrence = new RecurrencePattern()
{
DaysOfWeekMask = RecurrenceDays.WeekDays,
Frequency = RecurrenceFrequency.Weekly,
MaxOccurrences = 30
};
this.RestHours.Add(new BreakSlot()
{
Title = "Lunch time",
StartDate = today.AddHours(12),
EndDate = today.AddHours(13),
IsReadOnly = true,
RecurrencePattern = dailyRecurrence
});
this.RestHours.Add(new BreakSlot()
{
Title = "Coffee break",
StartDate = today.AddHours(16),
EndDate = today.AddHours(16).AddMinutes(30),
RecurrencePattern = dailyRecurrence
});
}
public ObservableCollection<BreakSlot> RestHours { get; set; }
}
Here is the RadCalendar definition where SpecialSlotContentTemplate property is applied:
<telerikInput:RadCalendar x:Name="calendar"
ViewMode="MultiDay"
SchedulingUiEnabled="True">
<telerikInput:RadCalendar.MultiDayViewSettings>
<telerikInput:MultiDayViewSettings VisibleDays="7"
SpecialSlotsSource="{Binding RestHours}"
SpecialSlotContentTemplate="{StaticResource RestHoursTemplate}"/>
</telerikInput:RadCalendar.MultiDayViewSettings>
</telerikInput:RadCalendar>
And, lastly, add the RestHoursDataTemplate referenced earlier as a StaticResource:
<DataTemplate x:Key="RestHoursTemplate">
<Label Text="{Binding Title}"
Margin="5"
TextColor="#29398D"
FontSize="10" />
</DataTemplate>
Below you can check the result on different platforms:
All the Special Slots examples can be found in the Calendar & Scheduling/Features folder of the SDK Samples Browser application.