在WPF应用程序中绑定可空的日期时间

4

我有一个WPF应用程序,其中我将此属性绑定到一个日期选择器

public Nullable<System.DateTime> dpc_date_engagement { get; set; }

所以我添加了一个转换器:
 public class DateConverter : IValueConverter
   {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
            return ((DateTime)value).ToShortDateString();
        return String.Empty;
    }

       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           string strValue = value.ToString();
           DateTime resultDateTime;
           return DateTime.TryParse(strValue, out resultDateTime) ? resultDateTime : value;
       }
   }

在XAML文件中:

                     <DatePicker >
                                <DatePicker.Text>
                                    <Binding Path="dpc_date_engagement" UpdateSourceTrigger="PropertyChanged">
                                        <Binding.Converter>
                                            <converter:DateConverter/>
                                        </Binding.Converter>
                                    </Binding>
                                </DatePicker.Text>
                            </DatePicker>

问题是当日期为空时,显示的文本为1/1/0001。

  • 我应该如何修改代码,在数值为空时显示空字符串而不是01/01/0001呢?

1
转换器中的断点是什么情况? - Yuri Dorokhov
@YuriDorokhov 对于 null 值,在 convert 方法中它会返回 value = 01/01/0001 00:00:00 - Lamloumi Afif
1
你尝试过设置一个样式,当值为null时将文本设置为“”吗? - Muds
有一个数据触发器在值x:null上,并将文本设置为“”。应该可以的。虽然我没有尝试过。如果您实施,请告诉我。 - Muds
1
@LamloumiAfif 显然,您的 Nullable<DataTime> 不包含 null 值,而是包含 DateTime.MinValue(或默认构造的 DateTime)。如果它包含 null 值,则转换表达式 (DateTime)value 将抛出异常。 - Clemens
@Clemens 那是真的,请将您的评论发布为答案,谢谢 ;) - Lamloumi Afif
3个回答

10

处理在DatePicker中使用的可空DateTime字段最简单的方法是将TargetNullValue='' 设置。

在XAML文件中:

<DatePicker Text={Binding dpc_date_engagement, Mode=TwoWay, TargetNullValue='', UpdateSourceTrigger=PropertyChanged} />

哇,这真的是最好的解决方案。我花了几个小时尝试将SelectedDate绑定到转换文本绑定上,但总是遇到其他问题。像这样将DateTime属性绑定到文本中也解决了只在失去焦点时更新SelectedDate绑定的问题。非常感谢。 - Momo
我们可以在TargetNullValue中设置文本吗?例如:TargetNullValue="未选择日期"? - paraJdox1

5
您的转换器传递给 Nullable 的值本身不是 null,即使它保存了一个 null 值(它甚至不能为 null,因为它是一个结构体,因此不可为空)。
因此,您需要将其强制转换为 Nullable ,然后检查其 HasValue 属性,而不是将 value 与 null 进行比较。
此外,您似乎在绑定属性中有类似于 DateTime.MinValue 的内容,而不是 null。因此,您也应该对其进行检查。
public object Convert(...)
{
    var nullable = (Nullable<DateTime>)value;

    if (nullable.HasValue && nullable.Value > DateTime.MinValue)
    {
        return nullable.Value.ToShortDateString();
    }

    return String.Empty;
}

对于空值,nullable = 01/01/0001 00:00:00,因此我得到了相同的结果。 - Lamloumi Afif

1

对我来说,我实际上需要在我的DatePicker中添加Mode=TwoWay属性。现在它可以完美地处理可空日期:

NullableDateConverter.cs

public class NullableDateConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is DateTime?))
            return string.Empty;

        var ndt = (DateTime?)value;
        if (ndt.HasValue)
            return ndt.Value.ToShortDateString();
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return DateTime.TryParse(value.ToString(), out var dateTime) ? dateTime : value;
    }
}

MainWindow.xaml

xmlns:conv="clr-namespace:Path.To.The.Converter.Folder"

...

<Window.Resources>
    <conv:NullableDateConverter x:Key="dateConverter"/>
</Window.Resources>

...

<DatePicker Text="{Binding SelectedDate, Mode=TwoWay, Converter={StaticResource dateConverter}}"/>

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