MVVM in Xamarin Calendar (SfCalendar)

10 Oct 202313 minutes to read

Binding SelectedDate

Calendar supports selecting a date programmatically by binding the SelectedDate property from your view model.

calendar.SetBinding(SfCalendar.SelectedDateProperty, new Binding("SelectedDate", BindingMode.TwoWay));
XAML:
<calendar:SfCalendar x:Name="calendar"
                     ShowInlineEvents="True"
                     SelectionMode="SingleSelection"
                     SelectedDate="{Binding SelectedDate, Mode=TwoWay}">
</calendar:SfCalendar>

The following code sample demonstrates the ViewModel class.

public class MainViewModel 
{
    public DateTime SelectedDate { get; set; }

    public MainViewModel()
    {
        SelectedDate = new DateTime(2019, 02, 05);
    }
}

NOTE

  • You can bind the SelectedDate property only when the SelectionMode is set to SingleSelection in calendar.

Binding SelectedDates

Calendar supports selecting dates programmatically by binding the SelectedDates property from your view model with the List<DateTime> type.

calendar.SetBinding(SfCalendar.SelectedDatesProperty, new Binding("SelectedDates", BindingMode.TwoWay));
<calendar:SfCalendar x:Name="calendar"
                     ShowInlineEvents="True"
                     SelectionMode="MultiSelection"
                     SelectedDates="{Binding SelectedDates, Mode=TwoWay}">
</calendar:SfCalendar>

The following code sample demonstrates the ViewModel class.

public class MainViewModel
{
    public List<DateTime> SelectedDates { get; set; }

    public MainViewModel()
    {
        SelectedDates = new List<DateTime>();
        SelectedDates.Add(new DateTime(2019, 02, 05));
        SelectedDates.Add(new DateTime(2019, 02, 08));
        SelectedDates.Add(new DateTime(2019, 02, 10));
        SelectedDates.Add(new DateTime(2019, 02, 14));
        SelectedDates.Add(new DateTime(2019, 02, 20));
    }

}

NOTE

  • You can bind the SelectedDates property only when SelectionMode is set to MultiSelection in calendar.

Binding SelectedRange

The calendar supports selecting a range of dates programmatically by binding the SelectedRange property with the SelectionRange type from your view model.

calendar.SetBinding(SfCalendar.SelectedRangeProperty, new Binding("SelectedRange", BindingMode.TwoWay));
<calendar:SfCalendar x:Name="calendar"
                     ShowInlineEvents="True"
                     SelectionMode="RangeSelection"
                     SelectedRange ="{Binding SelectedRange, Mode=TwoWay}">
</calendar:SfCalendar>

The following code sample demonstrates the ViewModel class.

public class MainViewModel
{
    public SelectionRange SelectedRange { get; set; }

    public MainViewModel()
    {
        SelectedRange = new SelectionRange();
        SelectedRange.StartDate = new DateTime(2019, 02, 10);
        SelectedRange.EndDate = new DateTime(2019, 02, 20);
    }
}

Calendar supports selecting multiple ranges of dates programmatically by binding the SelectedRange property with ObservableCollection<SelectionRange> type from your view model.

calendar.SetBinding(SfCalendar.SelectedRangeProperty, new Binding("SelectedRanges", BindingMode.TwoWay));
<calendar:SfCalendar x:Name="calendar"
                     ShowInlineEvents="True"
                     SelectionMode="MultiRangeSelection"
                     SelectedRange ="{Binding SelectedRanges, Mode=TwoWay}">
</calendar:SfCalendar>

The following code sample demonstrates the ViewModel class.

public class MainViewModel
{
    public ObservableCollection<SelectionRange> SelectedRanges { get; set; }

    public MainViewModel()
    {
        SelectedRanges = new ObservableCollection<SelectionRange>();
        SelectedRanges.Add(new SelectionRange()
        {
            StartDate = new DateTime(2019, 02, 10),
            EndDate = new DateTime(2019, 02, 20)
        });

        SelectedRanges.Add(new SelectionRange()
        {
            StartDate = new DateTime(2019, 01, 31),
            EndDate = new DateTime(2019, 02, 05)
        });
    }
}

NOTE

  • You can bind the SelectedRange property only when SelectionBinding is set to RangeSelection and MultiRangeSelection in calendar.

Commands

Tap command

The TapCommand will be triggered whenever tapping the calendar cell and passing the CalendarTappedEventArgs as parameter.

<calendar:SfCalendar x:Name="calendar"  TapCommand="{Binding CalendarCellTapped}">
              <calendar:SfCalendar.BindingContext>
              <local:CalendarViewModel/>
              </calendar:SfCalendar.BindingContext>
    </calendar:SfCalendar>
public class CalendarViewModel
{
  private string commandText;
  
  public string CommandText
  {
	get { return commandText; }
	set { commandText = value; }
  }
  
  public ICommand CalendarCellTapped { get; set; }
   
  public CalendarViewModel()
  {
	CalendarCellTapped = new Command<CalendarTappedEventArgs>(CellTapped);
  }
   
  private void CellTapped(CalendarTappedEventArgs obj)
  {
	CommandText = obj.DateTime.ToString("dd/MM/yyyy") + " " + obj.SelectedAppointment.ToString();
  }
 
}

Hold command

The HoldCommand will be triggered whenever the calendar cell is long pressed and passing the DayCellHoldingEventArgs as parameter.

<calendar:SfCalendar x:Name="calendar"  HoldCommand="{Binding OnDateCellHolding}">
              <calendar:SfCalendar.BindingContext>
              <local:CalendarViewModel/>
              </calendar:SfCalendar.BindingContext>
    </calendar:SfCalendar>
public class CalendarViewModel
{
  private string commandText;
  
  public string CommandText
  {
	get { return commandText; }
	set { commandText = value; }
  }
  
  public ICommand OnDateCellHolding { get; set; }
   
  public CalendarViewModel()
  {
	OnDateCellHolding = new Command<DateTime>(DateCellHolding);
  }
   
  private void DateCellHolding(DateTime obj)
  {
	CommandText = obj.ToString("dd/MM/yyyy") ;
  }
 
}

Month changed command

The MonthChangedCommand will be triggered whenever the navigating between month and Forward()/backward() is called in calendar and passing the MonthChangedEventArgs as parameter.

<calendar:SfCalendar x:Name="calendar"  MonthChangedCommand="{Binding OnMonthChanged}">
              <calendar:SfCalendar.BindingContext>
              <local:CalendarViewModel/>
              </calendar:SfCalendar.BindingContext>
    </calendar:SfCalendar>
public class CalendarViewModel
{
  private string commandText;
  public string CommandText
  {
	get { return commandText; }
	set { commandText = value; }
  }
  
  public ICommand OnMonthChanged { get; set; }
   
  public CalendarViewModel()
  {
	OnMonthChanged = new Command<MonthChangedEventArgs>(MonthChanged);
  }
   
  private void MonthChanged(MonthChangedEventArgs obj)
  {
	CommandText =" CurrentMonth -"+ " " +obj.CurrentValue.ToString("dd/MM/yyyy") +"  "+" PreviousMonth - "+"  " +  obj.PreviousValue.ToString("dd/MM/yyyy") +"  "+" VisibleDate  - "+ " "+ obj.VisibleDates[0].Date.ToString("dd/MM/yyyy");
  }
}

Selection changed command

The SelectionChangedCommand will be triggered whenever the selection is changed in calendar for the following selections and passing the SelectionChangedEventArgs as parameter.

  • SingleSelection - A single date can be selected in a month view which can be equipped when user needs to select one date at a time.
  • MultiSelection - More than one date can be selected.
  • RangeSelection - It allows us to select a single date range in calendar month view.
  • MultiRangeSelection - More than one date range can be selected in a month view.
<calendar:SfCalendar x:Name="calendar" SelectionChangedCommand="{Binding OnSelectionChanged}">
              <calendar:SfCalendar.BindingContext>
              <local:CalendarViewModel/>
              </calendar:SfCalendar.BindingContext>
    </calendar:SfCalendar>
public class CalendarViewModel
{
  private string selectionChangedCommandText;
  public string SelectionChangedCommandText
  {
	get { return selectionChangedCommandText; }
	set { selectionChangedCommandText = value; }
  }
  
  public ICommand OnSelectionChanged { get; set; }
   
  public CalendarViewModel()
  {
	OnSelectionChanged = new Command<SelectionChangedEventArgs>(SelectionChanged);
  }
   
  private void SelectionChanged(SelectionChangedEventArgs obj)
  {
	SelectionChangedCommandText = " DateAdded- " +obj.DateAdded?.Count.ToString() +"  "+ " DateRemoved- " + obj.DateRemoved?.Count.ToString() + "  " + " NewRangeAdded -"
	  + obj.NewRangeAdded?.Count.ToString();
  }
}

See also

How to bind SelectedDates of Calendar in MVVM?