Load on Demand

This article demonstrates how you can load the appointments in RadScheduleView depending on the current visible range of the control. This can be very useful in scenarios where the number of appointments is very large.

There are two possible approaches to accomplish this:

1. Using the VisibleRangeChanged event.

2. Using the VisibleRangeChangedCommand and VisibleRangeChangedCommandParameter properties. This approach is effective if you wish to load the visible appointments in an MVVM-friendly manner.

Using the VisibleRangeChanged Event

To accomplish this approach, you only need to handle the VisibleRangeChanged and create a helper method to get the appointments for a particular DateSpan. Please note that you need to start with an initial collection of appointments.

Example 1: Handling the VisibleRangeChanged event

private void ScheduleView_Loaded(object sender, RoutedEventArgs e) 
{ 
    this.scheduleView.AppointmentsSource = this.GenerateAppointmentsForRange(new DateSpan(DateTime.Now, DateTime.Now.AddDays(2))); 
    this.scheduleView.VisibleRangeChanged += ScheduleView_VisibleRangeChanged; 
} 
 
private void ScheduleView_VisibleRangeChanged(object sender, EventArgs e) 
{ 
    var scheduleView = sender as RadScheduleView; 
    var range = scheduleView.VisibleRange; 
    scheduleView.AppointmentsSource = this.GenerateAppointmentsForRange(range); 
} 
 
private ObservableCollection<Appointment> GenerateAppointmentsForRange(IDateSpan dateSpan) 
{ 
    ObservableCollection<Appointment> newSource = new ObservableCollection<Appointment>(); 
 
    newSource.AddRange( 
        from i in Enumerable.Range(0, (dateSpan.End - dateSpan.Start).Days * 24) 
        select new Appointment() 
        { 
            Subject = "Appointment" + i + " " + dateSpan.Start.AddHours(i).ToShortDateString(), 
            Start = dateSpan.Start.AddHours(i), 
            End = dateSpan.Start.AddHours(i + 1), 
        }); 
 
    return newSource; 
} 
Private Sub ScheduleView_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) 
    Me.scheduleView.AppointmentsSource = Me.GenerateAppointmentsForRange(New DateSpan(DateTime.Now, DateTime.Now.AddDays(2))) 
    Me.scheduleView.VisibleRangeChanged += ScheduleView_VisibleRangeChanged 
End Sub 
 
Private Sub ScheduleView_VisibleRangeChanged(ByVal sender As Object, ByVal e As EventArgs) 
    Dim scheduleView = TryCast(sender, RadScheduleView) 
    Dim range = scheduleView.VisibleRange 
    scheduleView.AppointmentsSource = Me.GenerateAppointmentsForRange(range) 
End Sub 
 
Private Function GenerateAppointmentsForRange(ByVal dateSpan As IDateSpan) As ObservableCollection(Of Appointment) 
    Dim newSource As New ObservableCollection(Of Appointment)() 
 
    newSource.AddRange( 
        From i In Enumerable.Range(0, (dateSpan.End - dateSpan.Start).Days * 24) 
        Select New Appointment() With { 
            .Subject = "Appointment" & i & " " & dateSpan.Start.AddHours(i).ToShortDateString(), 
            .Start = dateSpan.Start.AddHours(i), 
            .End = dateSpan.Start.AddHours(i + 1) 
        }) 
 
    Return newSource 
End Function 

Using the VisibleRangeChangedCommand

Alternatively, if you want to follow the MVVM pattern, you can create an appropriate command in your viewmodel and set it as the VisibleRangeChangedCommand of the RadScheduleView control.

For example, you can define your viewmodel as shown in Example 2.

Example 2: The ViewModel class

public class ViewModel : ViewModelBase 
{ 
    private ICommand visibleRangeChanged; 
    private ObservableCollection<Appointment> appointments; 
 
    public ViewModel() 
    { 
        this.Appointments = this.GenerateAppointmentsForRange(new DateSpan(DateTime.Now, DateTime.Now.AddDays(2))); 
        this.VisibleRangeChanged = new DelegateCommand(this.OnVisibleRangeExecuted, this.OnVisibleRangeCanExecute); 
    } 
 
    public ObservableCollection<Appointment> Appointments 
    { 
        get 
        { 
            return this.appointments; 
        } 
        private set 
        { 
            this.appointments = value; 
            this.OnPropertyChanged("Appointments"); 
        } 
    } 
 
    public ICommand VisibleRangeChanged 
    { 
        get 
        { 
            return this.visibleRangeChanged; 
        } 
        set 
        { 
            this.visibleRangeChanged = value; 
        } 
    } 
 
    private void OnVisibleRangeExecuted(object param) 
    { 
        // The param is bound to the VisibleRange property in XAML 
        this.GenerateAppointments(param as IDateSpan); 
    } 
 
    private bool OnVisibleRangeCanExecute(object param) 
    { 
        return param != null; 
    } 
 
    private void GenerateAppointments(IDateSpan dateSpan) 
    { 
        ObservableCollection<Appointment> newSource = new ObservableCollection<Appointment>(); 
 
        newSource.AddRange( 
            from i in Enumerable.Range(0, (dateSpan.End - dateSpan.Start).Days * 24) 
            select new Appointment() 
            { 
                Subject = "Appointment" + i + " " + dateSpan.Start.AddHours(i).ToShortDateString(), 
                Start = dateSpan.Start.AddHours(i), 
                End = dateSpan.Start.AddHours(i + 1), 
            }); 
 
        this.Appointments = newSource; 
    } 
} 
Public Class ViewModel 
    Inherits ViewModelBase 
 
    Private _visibleRangeChanged As ICommand 
    Private _appointments As ObservableCollection(Of Appointment) 
 
    Public Sub New() 
        Me.Appointments = Me.GenerateAppointmentsForRange(New DateSpan(DateTime.Now, DateTime.Now.AddDays(2))) 
        Me.VisibleRangeChanged = New DelegateCommand(AddressOf Me.OnVisibleRangeExecuted, AddressOf Me.OnVisibleRangeCanExecute) 
    End Sub 
 
    Public Property Appointments() As ObservableCollection(Of Appointment) 
        Get 
            Return Me._appointments 
        End Get 
        Private Set(ByVal value As ObservableCollection(Of Appointment)) 
            Me._appointments = value 
            Me.OnPropertyChanged("Appointments") 
        End Set 
    End Property 
 
    Public Property VisibleRangeChanged() As ICommand 
        Get 
            Return Me._visibleRangeChanged 
        End Get 
        Set(ByVal value As ICommand) 
            Me._visibleRangeChanged = value 
        End Set 
    End Property 
 
    Private Sub OnVisibleRangeExecuted(ByVal param As Object) 
        ' The param is bound to the VisibleRange property in XAML 
        Me.GenerateAppointments(TryCast(param, IDateSpan)) 
    End Sub 
 
    Private Function OnVisibleRangeCanExecute(ByVal param As Object) As Boolean 
        Return param IsNot Nothing 
    End Function 
 
    Private Sub GenerateAppointments(ByVal dateSpan As IDateSpan) 
        Dim newSource As New ObservableCollection(Of Appointment)() 
 
        newSource.AddRange( 
            From i In Enumerable.Range(0, (dateSpan.End - dateSpan.Start).Days * 24) 
            Select New Appointment() With { 
                .Subject = "Appointment" & i & " " & dateSpan.Start.AddHours(i).ToShortDateString(), 
                .Start = dateSpan.Start.AddHours(i), 
                .End = dateSpan.Start.AddHours(i + 1) 
            }) 
 
        Me.Appointments = newSource 
    End Sub 
End Class 

You can now bind the VisibleRangeChangedCommand and VisibleRangeChangedCommandParameter properties as demonstrated in Example 3.

Example 3: Binding the VisibleRangeChangedCommand and VisibleRangeChangedCommandParameter properties

<scheduleView:RadScheduleView x:Name="scheduleView" 
                            AppointmentsSource="{Binding Appointments}"  
                            VisibleRangeChangedCommand="{Binding VisibleRangeChanged}" 
                            VisibleRangeChangedCommandParameter="{Binding  VisibleRange, RelativeSource={RelativeSource Self}}"> 
... 
</scheduleView:RadScheduleView> 

See Also

In this article