CalendarDatePicker 绑定空值
CalendarDatePicker Binding Null Value
我正在使用 CalendarDatePicker
<CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/>
问题是当我绑定日期 属性 时,选择器不再显示默认的占位符文本(select 日期),而是现在显示 01.01.1916 如果 属性 为空(属性 始终设置为空)。
public DateTimeOffset? DisplayValue {get;set;}
如果我手动将 null 作为 Date 的值,它现在会再次显示 PlaceholderText。
DatePick.Date=null;
并且绑定仍然 works/i`m 在选择日期时返回所需的值。
那么是否可以在不使用代码隐藏的情况下显示占位符文本?
在 class 和 属性 您需要实现接口 INotifyPropertyChanged。在 属性 DisplayValue 中,您必须调用 onPropertyChanged 方法。
示例代码:
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;
}
}
自定义 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));
}
}
我找到了可行的解决方案。
因此我扩展了默认的 calendarDatePicker。
我添加了一个额外的可绑定 属性,它既可以用作选择日期的默认值 Setter,也可以在需要时用作日期值的 Setter。
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;
}
}
}));
}
似乎 calendardatepicker "min value" 总是当前年份减去 100,我已经将你的代码修改为:
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;
}
}
}));
}
首选方案
如果您使用 x:Bind 而不是 Binding,一切都会按预期工作,如果绑定日期值为 null,您可以看到占位符。
直接在 XAML 页面中:
<CalendarDatePicker Date="{x:Bind DataContext.DisplayValue, Mode=TwoWay}"/>
或在数据模板中:
<DataTemplate x:Key="DateFieldItemTemplate"
x:DataType="DataModel:ObjectTypeWithDate">
<Grid>
<CalendarDatePicker Date="{x:Bind DateField, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
我的解决方案,对我来说效果很好
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;
}
}
}
我正在使用 CalendarDatePicker
<CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/>
问题是当我绑定日期 属性 时,选择器不再显示默认的占位符文本(select 日期),而是现在显示 01.01.1916 如果 属性 为空(属性 始终设置为空)。
public DateTimeOffset? DisplayValue {get;set;}
如果我手动将 null 作为 Date 的值,它现在会再次显示 PlaceholderText。
DatePick.Date=null;
并且绑定仍然 works/i`m 在选择日期时返回所需的值。 那么是否可以在不使用代码隐藏的情况下显示占位符文本?
在 class 和 属性 您需要实现接口 INotifyPropertyChanged。在 属性 DisplayValue 中,您必须调用 onPropertyChanged 方法。
示例代码:
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;
}
}
自定义 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));
}
}
我找到了可行的解决方案。 因此我扩展了默认的 calendarDatePicker。 我添加了一个额外的可绑定 属性,它既可以用作选择日期的默认值 Setter,也可以在需要时用作日期值的 Setter。
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;
}
}
}));
}
似乎 calendardatepicker "min value" 总是当前年份减去 100,我已经将你的代码修改为:
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;
}
}
}));
}
首选方案
如果您使用 x:Bind 而不是 Binding,一切都会按预期工作,如果绑定日期值为 null,您可以看到占位符。
直接在 XAML 页面中:
<CalendarDatePicker Date="{x:Bind DataContext.DisplayValue, Mode=TwoWay}"/>
或在数据模板中:
<DataTemplate x:Key="DateFieldItemTemplate"
x:DataType="DataModel:ObjectTypeWithDate">
<Grid>
<CalendarDatePicker Date="{x:Bind DateField, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
我的解决方案,对我来说效果很好
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;
}
}
}