日历日期选择器绑定空值

6
我正在使用一个CalendarDatePicker。
<CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/>

问题是当我绑定日期属性时,选择器不再显示默认的占位文本“选择日期”,而是如果该属性为空(该属性始终为null),则现在显示01.01.1916。
public DateTimeOffset? DisplayValue {get;set;}

如果我手动将null作为日期的值,它会重新显示PlaceholderText。
DatePick.Date=null;

绑定仍然有效,当选择日期时,我可以得到想要的值。那么有没有可能在不使用codebehind的情况下显示占位符文本?


你的XAML代码中缺少了一个斜杠: <CalendarDatePicker x:Name="DatePick" DisplayMode="Decade" Date="{Binding DisplayValue, Mode=TwoWay}"/> 但这不是问题。;) - Sean Stayns
4个回答

3

似乎日历日期选择器的“最小值”始终是当前年份减去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 内部:

<DataTemplate x:Key="DateFieldItemTemplate"
              x:DataType="DataModel:ObjectTypeWithDate">
    <Grid>
        <CalendarDatePicker Date="{x:Bind DateField, Mode=TwoWay}"/>
    </Grid>
</DataTemplate>

如果控件在数据模板中,我该如何使x:Bind起作用? - Lance
1
你必须在DataTemplate标签内使用x:DataType属性来设置绑定对象的类型。 - Asier Peña

2

我找到了一个可行的解决方案。因此,我扩展了默认的calendarDatePicker。我添加了一个额外的绑定属性,既可以作为选择日期的默认值设置器,也可以在需要时作为日期值的设置器。

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;
      }
    }
  }));
}

1
我的解决方案,对我来说工作得很好。
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;
        }
    }
}

我使用情况下最简单的解决方案 :) - xmashallax

-1
在具有属性的类中,您需要实现接口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;
    }
}

自定义类 (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));
        }
    }

1
我正在使用类似的方法,但这不是问题所在。 问题在于,如果我绑定null/将绑定的变量设置为null,则它会显示1.1.1916而不是占位文本。 - Olias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接