1

I want to do a two way bind from my ViewModel to selected date (single) in my XAML calendarview. But we have no dependency properties to do it.

What to do ?

EDIT: the code I tried but I got Error. Its the combination of these two topics: How to use CalenderView in UWP MVVM How to select rang of dates on finger slide on Calendar Control - UWP Win10 VS2015 XAML:

<CalendarView  MinHeight="250" MaxHeight="500" MaxWidth="720"   FontWeight="Normal" 
             DayItemFontWeight="Light" MinWidth="100"
                          SelectionMode="Single"
                          Style="{StaticResource Mahcalenderstyle}" Visibility="Visible" 
             HorizontalAlignment="Stretch" x:Name="MyCalendarView" DisplayMode="Month" Margin="9,25,9,0"
             VerticalAlignment="Top" SelectedDatesChanged="CalendarView_SelectedDatesChanged"
             CalendarViewDayItemStyle="{StaticResource CalendarViewDayItemStyle1}"
                          />

And my VM:

 private DateTimeOffset _selecteddate;
    public DateTimeOffset SelectedDate
    {
        get
        {
            return _selecteddate;

        }
        set
        {

            if (_selecteddate != value)
            {
                _selecteddate = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this,
                        new PropertyChangedEventArgs("SelectedDate"));
                }
            }
        }
    }
    public CalendarViewModel()
    {

        SelectedDate = DateTimeOffset.Now;}

The helper:

 public static class CalendarViewHelper
{
    public static IList<DateTimeOffset> GetSelectedDates(DependencyObject obj)
    {
        return (IList<DateTimeOffset>)obj.GetValue(SelectedDatesProperty);
    }

    public static void SetSelectedDates(DependencyObject obj, IList<DateTimeOffset> value)
    {
        obj.SetValue(SelectedDatesProperty, value);
    }

    public static readonly DependencyProperty SelectedDatesProperty =
        DependencyProperty.RegisterAttached("SelectedDates", typeof(IList<DateTimeOffset>), typeof(CalendarView),
            new PropertyMetadata(null, (d, e) =>
            {
                var cv = d as CalendarView;
                var dates = e.NewValue as IList<DateTimeOffset>;

                if (cv != null && dates != null)
                {
                    foreach (var date in dates)
                    {
                        cv.SelectedDates.Add(date);
                    }
                }
            }));

}
Community
  • 1
  • 1
Mohsen
  • 427
  • 4
  • 20

1 Answers1

3

You need to create an attached property of a DateTimeOffset, not an IList<DateTimeOffset> since you only want to select one date.

So instead of the code you copied over from my other answer, you will need something like this -

public static class CalendarViewHelper
{
    public static DateTimeOffset GetSelectedDate(DependencyObject obj)
    {
        return (DateTimeOffset)obj.GetValue(SelectedDateProperty);
    }

    public static void SetSelectedDate(DependencyObject obj, DateTimeOffset value)
    {
        obj.SetValue(SelectedDateProperty, value);
    }

    public static readonly DependencyProperty SelectedDateProperty =
        DependencyProperty.RegisterAttached("SelectedDate", typeof(DateTimeOffset), typeof(CalendarView),
            new PropertyMetadata(null, (d, e) =>
            {
                var cv = (CalendarView)d;
                var date = (DateTimeOffset)e.NewValue;

                cv.SelectedDates.Clear();
                cv.SelectedDates.Add(date);
            }));
}

Note you will need to call Clear to clear all the previously selected date(s) because the SelectionMode is set to Single, without doing so, an error will be thrown.

Then you will just need to hook it up in xaml with your SelectedDate property.

<CalendarView SelectionMode="Single"
                  DisplayMode="Month"
                  local:CalendarViewHelper.SelectedDate="{x:Bind SelectedDate, Mode=OneWay}" />
Justin XL
  • 38,763
  • 7
  • 88
  • 133