We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

How to select week in calendar xamarin.forms?

Platform: Xamarin.Forms |
Control: SfCalendar

Calendar week selection

Xamarin.Forms calendar supports selecting the entire week using the selection mode is 'RangeSelection' and binding ' SelectedDates ' property of SfCalendar using the MVVM pattern. Calendar week day collection will be retrieved from giving a single selected date in the calendar. Based on the selected date we can generate all calendar week days and bind it to `SelectedDates`.

Step 1

Create a `ViewModel` class and add `SelectedDays` property in the `CalendarViewModel` class.

C#:

    public class CalendarViewModel : INotifyPropertyChanged
    {
        private SelectionRange selectedDays;
        
        /// <summary>
        /// Selected Days
        /// </summary>
        public SelectionRange SelectedDays
        {
            get
            {
                return selectedDays;
            }
            set
            {
                selectedDays = value;
                RaisePropertyChanged("SelectedDays");
            }
        }
 
        /// <summary>
        /// Property changed event handler
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
 
        /// <summary>
        /// Raising Property changed event
        /// </summary>
        /// <param name="propertyName"></param>
        public void RaisePropertyChanged(string propertyName)
        {
            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Step 2

Create the `CalendarBehavior` class and wire the `SelectionChanged` event for week selection. You can get selected date from ` SelectionChanged` event and based on the selected date you can generate calendar week days by calling ` GetTotalWeekDays()`.

C#:

   /// <summary>
    /// Calendar Behavior class
    /// </summary>
    public class CalendarBehavior : Behavior<ContentPage>
    {
        private CalendarViewModel viewModel;
        private readonly IList<int> weekNumbers = new List<int>();
 
        /// <summary>
        /// Begins when the behavior attached to the view. 
        /// </summary>
        /// <param name="bindable">bindable value</param>
        protected override void OnAttachedTo(BindableObject bindable)
        {
            base.OnAttachedTo(bindable);
            var calendar = (bindable as MainPage).FindByName<SfCalendar>("calendar");
            if (calendar == null)
            {
                return;
            }
 
            calendar.SelectionChanged += Calendar_SelectionChanged;
        }
 
        /// <summary>
        /// Selection Changed event
        /// </summary>
        /// <param name="sender">return the object</param>
        /// <param name="e">Selection Changed Event Args</param>
        private void Calendar_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (viewModel == null)
            {
                viewModel = (CalendarViewModel)(sender as SfCalendar).BindingContext;
            }
 
            if (e.DateAdded.Count == 0)
            {
                viewModel.SelectedDays = GetTotalWeekDays(e.DateAdded[0]);
            }
            else
            {
                if (GetWeekOfYear(e.DateAdded[0]) != GetWeekOfYear(e.DateAdded[e.DateAdded.Count - 1]))
                {
                    viewModel.SelectedDays = GetTotalWeekDays(e.DateAdded[0], e.DateAdded[e.DateAdded.Count - 1]);
                }
                else
                {
                    viewModel.SelectedDays = GetTotalWeekDays(e.DateAdded[0]);
                }
            }
        }
 
        /// <summary>
        /// Retrieve Week Days from the given date ranges.
        /// </summary>
        /// <param name="startDateRange">dateTime value</param>
        /// <param name="endDateRange">endDateTime value</param>
        /// <returns></returns>
        public SelectionRange GetTotalWeekDays(DateTime startDateRange, DateTime? endDateRange = null)
        {
            if (endDateRange == null)
            {
                var days = DayOfWeek.Sunday - startDateRange.DayOfWeek;
                var startDate = startDateRange.AddDays(days);
                ObservableCollection<DateTime> dates = new ObservableCollection<DateTime>();
                for (var i = 0; i < 7; i++)
                {
                    dates.Add(startDate.Date);
                    startDate = startDate.AddDays(1);
                }
 
                return new SelectionRange(dates[0], dates[dates.Count - 1]);
            }
            else
            {
                ObservableCollection<DateTime> dates = new ObservableCollection<DateTime>();
                var startDayOfWeek = DayOfWeek.Sunday - startDateRange.DayOfWeek;
                var startDate = startDateRange.AddDays(startDayOfWeek);
 
                var endDayOfWeek = DayOfWeek.Saturday - endDateRange?.DayOfWeek;
                var endDate = endDateRange?.AddDays((int)endDayOfWeek);
 
                var difference = (endDate - startDate);
 
                for (var i = 0; i < ((TimeSpan)difference).Days + 1; i++)
                {
                    dates.Add(startDate.Date);
                    startDate = startDate.AddDays(1);
                }
 
                return new SelectionRange(dates[0], dates[dates.Count - 1]);
            }
        }
 
        /// <summary>
        /// Method for Get Week
        /// </summary>
        /// <param name="time">time value</param>
        /// <returns></returns>
        public static int GetWeekOfYear(DateTime time)
        {
            DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
            if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
            {
                time = time.AddDays(3);
            }
            return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday);
        }
    }

Step 3

Now bind the `SelectedDays` property of the `ViewModel` class with Calendar `SelectedRange` property, set the `SelectionMode` as `RangeSelection` and `CalendarViewModel` as the `BindingContext` for the calendar

XAML:

    <ContentPage.Content>
        <calendar:SfCalendar x:Name="calendar" 
                             SelectionMode="RangeSelection" 
                             SelectedRange="{Binding SelectedDays}">
       <calendar:SfCalendar.BindingContext>
                <local:CalendarViewModel/>
      </calendar:SfCalendar.BindingContext>
        </calendar:SfCalendar>
       <ContentPage.Behaviors>
           <local:CalendarBehavior />
       </ContentPage.Behaviors>   
    </ContentPage.Content>

Sample outputs:

Selection of calendar week days

Figure 1: Selecting single of calendar week by single selection

Swiping selection of calendar week days

Figure 2: Selecting multiple of calendar weeks by swiping selected weeks.

 

Sample link: https://github.com/SyncfusionExamples/calendar-week-selection

2X faster development

The ultimate Xamarin UI toolkit to boost your development speed.
ADD COMMENT
You must log in to leave a comment

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile