Reputation: 411
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?
Upvotes: 6
Views: 2123
Reputation: 3034
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;
}
}
}
Upvotes: 1
Reputation: 378
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;
}
}
}));
}
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>
Upvotes: 3
Reputation: 411
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;
}
}
}));
}
Upvotes: 2
Reputation: 4244
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));
}
}
Upvotes: -1