【问题标题】:CalendarDatePicker Binding Null ValueCalendarDatePicker 绑定空值
【发布时间】:2020-08-13 19:26:39
【问题描述】:

我正在使用 CalendarDatePicker

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

问题是当我绑定日期属性时,选择器不再显示默认占位符文本(选择日期),而是现在显示 01.01.1916 如果属性为空(属性始终设置为空)。

public DateTimeOffset? DisplayValue {get;set;}

如果我手动将 null 作为 Date 的值,它现在会再次显示 PlaceholderText。

DatePick.Date=null;

并且绑定仍然有效/我在选择日期时获得了所需的值。 那么是否有可能在不使用代码隐藏的情况下显示占位符文本?

【问题讨论】:

  • 您的 xaml 代码忘记了 /: 但它不是问题。 ;)

标签: c# asp.net xaml uwp model-binding


【解决方案1】:

似乎日历日期选择器“最小值”始终是当前年份减去 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,则所有工作都按预期工作,并且如果绑定的日期值为空,您可以看到占位符。

直接在 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 工作?
  • 您必须使用 DataTemplate 标签内的 x:DataType 属性来设置绑定对象的类型
【解决方案2】:

我找到了一个可行的解决方案。 因此我扩展了默认的 calendarDatePicker。 我添加了一个额外的可绑定属性,它既可以用作选择日期的 defaultValue 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;
      }
    }
  }));
}

【讨论】:

    【解决方案3】:

    我的解决方案,对我来说效果很好

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

    【讨论】:

    • 我的用例最简单的解决方案:)
    【解决方案4】:

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

    【讨论】:

    • 我正在使用类似的方法,但这不是问题。问题是,如果我绑定 null/将绑定变量设置为 null,它会显示 1.1.1916 而不是占位符文本。
    猜你喜欢
    • 2018-07-31
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 2013-04-09
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多