CalendarDatePicker Binding Null Value
Asked Answered
B

4

6

I´m using a CalendarDatePicker

<CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/>

The Problem is when i bind the Date Property the Picker doesn't display the default Placeholder Text(select a date) anymore, instead it now displays 01.01.1916 if the property is null(The Property is always set null).

public DateTimeOffset? DisplayValue {get;set;}

if i manually put null as a value for Date, it now displays the PlaceholderText again.

DatePick.Date=null;

And the binding still works/i`m getting the desired values back when picking a date. So is there an possibility to display the placeholder text without the using the codebehind?

Bastardize answered 29/9, 2016 at 16:27 Comment(1)
You forget a / by your xaml-code: <CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/> but it's not the problem. ;)Westhead
S
3

Seems that the calendardatepicker "min value" is always the current year less 100, I've modified your code in my side to:

  public class CalendarDatePickerEx : CalendarDatePicker
  {
    public DateTimeOffset? DefaultValue { get; set; }

    public static readonly DependencyProperty DefaultValueProperty =
      DependencyProperty.Register("DefaultValue", typeof(DateTimeOffset), typeof(CalendarDatePickerEx), new PropertyMetadata(null, (sender, e) =>
      {
        if ((DateTimeOffset?)e.NewValue != null && ((CalendarDatePickerEx)sender).Date.Value.Date.Year == DateTime.Today.Year - 100)
        {
          ((CalendarDatePickerEx)sender).SetDisplayDate((DateTimeOffset)e.NewValue);
          ((CalendarDatePickerEx)sender).Date = null;
        }
        else if ((DateTimeOffset?)e.NewValue == null && ((CalendarDatePickerEx)sender).Date.Value.Date.Year == DateTime.Today.Year - 100)
        {
          {
            ((CalendarDatePickerEx)sender).SetDisplayDate(DateTimeOffset.Now);
            ((CalendarDatePickerEx)sender).Date = null;
          }
        }
      }));
  }

Preferred solution

If you use x:Bind instead of Binding all works as expected and you can see the placeholder if the binded date value is null.

Directly in the XAML page:

<CalendarDatePicker Date="{x:Bind DataContext.DisplayValue, Mode=TwoWay}"/>

or inside a DataTemplate:

<DataTemplate x:Key="DateFieldItemTemplate"
              x:DataType="DataModel:ObjectTypeWithDate">
    <Grid>
        <CalendarDatePicker Date="{x:Bind DateField, Mode=TwoWay}"/>
    </Grid>
</DataTemplate>
Sleepwalk answered 7/7, 2017 at 11:37 Comment(2)
How can I make x:Bind work if the control is in a datatemplate?Porte
You have to use the x:DataType attribute inside the DataTemplate tag to set the type of your binded objectChili
B
2

I found a working solution. Therefore i expanded the default calendarDatePicker. I added an additional bindable Property which functions both as a defaultValue Setter for picking a Date and as a Setter for the Date value when needed.

public class CustomNewCalendarDatePicker : CalendarDatePicker
{
public DateTimeOffset? DefaultValue { get; set; }

public static readonly DependencyProperty DefaultValueProperty =
  DependencyProperty.Register("DefaultValue", typeof(DateTimeOffset), typeof(CustomNewCalendarDatePicker), new PropertyMetadata(null, (sender, e) =>
  {
    if ((DateTimeOffset?)e.NewValue != null && ((CustomNewCalendarDatePicker)sender).Date.Value.Date.Year == 1916)
    {
      ((CustomNewCalendarDatePicker)sender).SetDisplayDate((DateTimeOffset)e.NewValue);
      ((CustomNewCalendarDatePicker)sender).Date = null;
    }
    else if ((DateTimeOffset?)e.NewValue == null && ((CustomNewCalendarDatePicker)sender).Date.Value.Date.Year == 1916)
    {
      {
        ((CustomNewCalendarDatePicker)sender).SetDisplayDate(DateTimeOffset.Now);
        ((CustomNewCalendarDatePicker)sender).Date = null;
      }
    }
  }));
}
Bastardize answered 7/10, 2016 at 13:51 Comment(0)
E
2

My Solution, It's working fine for me

public class CalendarDatePickerExt : CalendarDatePicker
{
    public CalendarDatePickerExt()
    {
        this.DateChanged += CalendarDatePickerExt_DateChanged;
    }

    private void CalendarDatePickerExt_DateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs args)
    {
        if (args.NewDate != null && args.NewDate.Value.Year == DateTime.Today.Year - 100)
        {
            this.SetDisplayDate(DateTimeOffset.Now);
            this.Date = null;
        }
    }
}
Entomophilous answered 13/8, 2020 at 11:26 Comment(1)
Most simple solution for my use case :)Gyniatrics
W
-1

In the class with the property you need to implement the interface INotifyPropertyChanged. In the property DisplayValue you must call the onPropertyChanged-method.

Example Code:

Xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/>
</Grid>

MainPage.cs:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        ViewModel viewModel = new ViewModel();
        DataContext = viewModel;
    }
}

Custom Class (ViewModel):

class ViewModel : INotifyPropertyChanged
    {

        private DateTimeOffset _displayValue;

        public DateTimeOffset? DisplayValue
        {
            get
            {
                return _displayValue;
            }
            set
            {
                if (value != null) _displayValue = value.Value;
                OnPropertyChanged();
            }
        }

        public ViewModel()
        {
            DisplayValue = new DateTimeOffset(2016, 9, 29, 6, 39, 10, 3, new TimeSpan());
        }




        public event PropertyChangedEventHandler PropertyChanged;


        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
Westhead answered 29/9, 2016 at 16:49 Comment(1)
I am using a similar approach but that`s not the problem. The problem is that if i bind null/ set the binded variable null it displays the 1.1.1916 instead of the placeholdertext.Bastardize

© 2022 - 2024 — McMap. All rights reserved.