UWP CalendarView добавление выбранных дней не изменяет видимый месяц

#c# #uwp #behavior #calendarview

#c# #uwp #поведение #calendarview

Вопрос:

Я использую CalendarView с пользовательским поведением для выбора целой недели, когда пользователь нажимает на день, и это работает нормально. Однако, если я выбираю неделю не в текущем месяце, дни выделяются, но мне приходится менять месяц вручную — представление не обновляется и остается в текущем месяце… есть идеи, как изменить представление, чтобы автоматически показывать месяц с выбранными днями?

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 amp;amp; 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 amp;amp; 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>
  

Комментарии:

1. Проблема решена путем добавления sender.SetDisplayDate(vm.SelectedDate); в конце метода CalendarViewDayItemChanging 🙂

2. Пожалуйста, напишите свой собственный ответ и примите его, чтобы вопрос был решен 🙂

3. Ок, хорошая идея 🙂

4. Просто отметьте это как решение сейчас 🙂

Ответ №1:

Проблема решена путем добавления метода sender.SetDisplayDate(vm.SelectedDate) to CalendarLoaded , который присваивается Loaded атрибуту в CalendarView в CalendarPage.xaml.

Обновлено 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 amp;amp; 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);
    }