zanetam
zanetam

Reputation: 33

UWP CalendarView adding SelectedDays doesn't change visible month

I'm using CalendarView with the custom behavior to select whole week when user clicks on the day and it works fine. However if I select the week not on current month, days are highlighted but I have to change the month manually - the view is not updated and stays on current month... any idea how to change the view to show month with selected days automatically?

WeekHighlightBehavior.cs

public class WeekHighlightBehavior : Behavior
        {
            public CalendarView CalendarControl
            {
                get { return (CalendarView)GetValue(CalendarProperty); }
                set { SetValue(CalendarProperty, value); }
            }

            // Using a DependencyProperty as the backing store for Calendar.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty CalendarProperty =
                DependencyProperty.Register("CalendarControl", typeof(CalendarView), typeof(WeekHighlightBehavior), new PropertyMetadata(0));

            protected override void OnAttached()
            {
                base.OnAttached();
                CalendarControl.SelectedDatesChanged += Calendar_SelectedDatesChanged;
            }

            private void Calendar_SelectedDatesChanged(CalendarView sender, CalendarViewSelectedDatesChangedEventArgs args)
            {
                var dayItem = this.AssociatedObject as CalendarViewDayItem;
                var calendar = CultureInfo.CurrentUICulture.Calendar;
                bool highlight = false;
                if (args.AddedDates != null && args.AddedDates.Count() > 0)
                {
                    foreach (var date in args.AddedDates)
                    {
                        if (calendar.GetWeekOfYear(date.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday) ==
                            calendar.GetWeekOfYear(dayItem.Date.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
                        {
                            highlight = true;
                            break;
                        }
                    }
                }

                if (highlight)
                {
                    dayItem.Background = new SolidColorBrush(Color.FromArgb(255, 223, 231, 241));
                }
                else
                {
                    dayItem.Background = null;
                }
            }

            protected override void OnDetaching()
            {
                base.OnDetaching();
                CalendarControl.SelectedDatesChanged -= Calendar_SelectedDatesChanged;
            }
        }

CalendarPage.xaml.cs

private void CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
                {
                    var behavior = new WeekHighlightBehavior();
                    behavior.CalendarControl = sender;
                    Interaction.GetBehaviors(args.Item).Clear();
                    Interaction.GetBehaviors(args.Item).Add(behavior);
                    var vm = ServiceLocator.Current.GetInstance<SampleViewModel>();
                    if (sender.SelectedDates != null && sender.SelectedDates.Count() > 0)
                    {
                        foreach (var day in sender.SelectedDates)
                        {
                            sender.SelectedDates.Remove(day);
                        }
                    }
                    sender.SelectedDates.Add(vm.SelectedDate);
                }

private void SelectedDateChanged(object sender, CalendarViewSelectedDatesChangedEventArgs e)
                {
                    var vm = ServiceLocator.Current.GetInstance<SampleViewModel>();
                    if (e.AddedDates == null || e.AddedDates.Count() == 0)
                    {
                        return;
                    }
                    vm.SelectedDate = e.AddedDates.FirstOrDefault().DateTime;
                }

CalendarPage.xaml

<CalendarView SelectedDatesChanged="SelectedDateChanged" CalendarItemBorderThickness="0" IsTodayHighlighted="False" CalendarItemBackground="#ffffff" SelectedBorderBrush="#DFE7F1" FirstDayOfWeek="Monday" CalendarViewDayItemChanging="CalendarViewDayItemChanging">
                    <CalendarView.CalendarViewDayItemStyle>
                        <Style TargetType="CalendarViewDayItem">
                            <Setter Property="Padding" Value="0" />
                            <Setter Property="Margin" Value="0" />
                        </Style>
                    </CalendarView.CalendarViewDayItemStyle>
                </CalendarView>

Upvotes: 0

Views: 292

Answers (1)

zanetam
zanetam

Reputation: 33

Problem solved by adding sender.SetDisplayDate(vm.SelectedDate) to CalendarLoaded method, which is assigned to Loaded attribute in CalendarView in CalendarPage.xaml.

Updated CalendarPage.xaml.cs

private void CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
    {
        var behavior = new WeekHighlightBehavior();
        behavior.CalendarControl = sender;
        Interaction.GetBehaviors(args.Item).Clear();
        Interaction.GetBehaviors(args.Item).Add(behavior);
    }

private void CalendarLoaded(object sender, RoutedEventArgs args)
    {
        var calendar = sender as CalendarView;
        if (calendar.SelectedDates != null && calendar.SelectedDates.Count() > 0)
        {
            foreach (var day in calendar.SelectedDates)
            {
                calendar.SelectedDates.Remove(day);
            }
        }
        var vm = ServiceLocator.Current.GetInstance<SampleViewModel>();
        calendar.SetDisplayDate(vm.SelectedDate);
        calendar.SelectedDates.Add(vm.SelectedDate);
    }

Upvotes: 2

Related Questions