You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WPF DatePicker日期存显格式不一致问题解决方案问询

问题:WPF DatePicker日期显示与数据库存储格式不一致的解决

场景描述

现有SQLite数据库表,对应WPF模型Bills的日期字段(BillDt、DueDt)为string类型,数据库存储格式为yyyy-MM-dd。使用DatePicker控件选择日期时,已通过样式设置显示格式为dd-MM-yyyy,但修改日期后保存到数据库的格式变为dd-MM-yyyy 00:00:00,不符合要求。

相关代码:

  • 模型类:
public class Bills : ViewModelBase
{
    private int _id;
    public int Id
    {
        get { return _id; }
        set { SetValue(ref _id, value); }
    }

    private string _billDt;
    public string BillDt
    {
        get { return _billDt; }
        set { SetValue(ref _billDt, value); }
    }

    private string _amt;
    public string Amt
    {
        get { return _amt; }
        set { SetValue(ref _amt, value); }
    }

    private string _dueDt;
    public string DueDt
    {
        get { return _dueDt; }
        set { SetValue(ref _dueDt, value); }
    }
}
  • DatePicker绑定:
<DatePicker
    FontSize="14"
    SelectedDate="{Binding BillDt, BindingGroupName=Group1, UpdateSourceTrigger=PropertyChanged}"
    Grid.Column="1"
    Grid.Row="3"/>
  • DatePickerTextBox样式:
<Style TargetType="{x:Type DatePickerTextBox}">
    <Setter Property="IsReadOnly" Value="True"/>
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <TextBox x:Name="PART_TextBox"
                         Text="{Binding Path=SelectedDate, StringFormat='dd-MM-yyyy',
                RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

解决方案

核心问题

直接将string类型的模型字段绑定到DatePicker.SelectedDate(DateTime?类型)时,WPF默认转换器会生成带时间部分的字符串,导致存储格式错误。必须通过**自定义IValueConverter**精确控制日期与字符串的转换逻辑。

步骤1:实现双向IValueConverter

创建转换器类,负责在数据库格式字符串(yyyy-MM-dd)和DateTime?之间双向转换:

using System;
using System.Globalization;
using System.Windows.Data;

public class DateStringConverter : IValueConverter
{
    // 模型→控件:将yyyy-MM-dd字符串转为DateTime?供DatePicker使用
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string dateStr 
            && DateTime.TryParseExact(dateStr, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
        {
            return date;
        }
        return null;
    }

    // 控件→模型:将DateTime转为yyyy-MM-dd字符串供存储
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is DateTime date)
        {
            return date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
        }
        return null;
    }
}

步骤2:在XAML中引用转换器

在窗口/用户控件的资源中添加转换器实例(或全局注册到App.xaml):

<Window.Resources>
    <local:DateStringConverter x:Key="DateStringConverter"/>
</Window.Resources>

注意:local是你的项目命名空间,需根据实际情况替换。

步骤3:修改DatePicker绑定

更新绑定配置,添加转换器:

<DatePicker
    FontSize="14"
    SelectedDate="{Binding BillDt, BindingGroupName=Group1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DateStringConverter}}"
    Grid.Column="1"
    Grid.Row="3"/>

步骤4:保留现有显示样式

你已设置的DatePickerTextBox样式会继续以dd-MM-yyyy格式显示日期,无需修改。


可选优化:调整模型字段类型

如果允许修改模型,建议将BillDt、DueDt改为DateTime?类型,更符合数据类型规范,也能简化逻辑:

private DateTime? _billDt;
public DateTime? BillDt
{
    get { return _billDt; }
    set { SetValue(ref _billDt, value); }
}

private DateTime? _dueDt;
public DateTime? DueDt
{
    get { return _dueDt; }
    set { SetValue(ref _dueDt, value); }
}

此时无需转换器,直接绑定SelectedDate即可,保存到数据库时再将DateTime?转为yyyy-MM-dd字符串:

// 保存逻辑示例
string dbBillDt = BillDt?.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
// 将dbBillDt写入SQLite数据库

内容的提问来源于stack exchange,提问作者Tamal Banerjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:26:52