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

WPF .NET Framework中Material Design日期选择器的贾拉利日历适配问题

解决WPF DatePicker贾拉利(Jalali)日历显示与输入不匹配问题

默认WPF DatePicker设置Language="fa-IR"后,仅做了本地化数字转换,底层仍使用公历(GregorianCalendar),导致选择面板和文本框显示不一致。要实现全贾拉利日历的显示与输入,需从日历控件替换和日期格式转换两方面处理:

1. 自定义日期转换器

创建IValueConverter实现公历DateTime到贾拉利日期字符串的双向转换,确保文本框显示正确的贾拉利日期:

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

public class GregorianToJalaliConverter : IValueConverter
{
    private static readonly PersianCalendar _persianCalendar = new PersianCalendar();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is DateTime dateTime && dateTime != DateTime.MinValue)
        {
            int year = _persianCalendar.GetYear(dateTime);
            int month = _persianCalendar.GetMonth(dateTime);
            int day = _persianCalendar.GetDayOfMonth(dateTime);
            // 用fa-IR文化自动格式化波斯数字
            return string.Format(new CultureInfo("fa-IR"), "{0}/{1}/{2}", year, month.ToString("00"), day.ToString("00"));
        }
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 处理手动输入的贾拉利日期转换回DateTime(可选,若禁用手动输入可返回Binding.DoNothing)
        if (value is string jalaliDate && !string.IsNullOrEmpty(jalaliDate))
        {
            try
            {
                string[] parts = jalaliDate.Split('/');
                if (parts.Length == 3)
                {
                    int year = int.Parse(parts[0], culture);
                    int month = int.Parse(parts[1], culture);
                    int day = int.Parse(parts[2], culture);
                    return _persianCalendar.ToDateTime(year, month, day, 0, 0, 0, 0);
                }
            }
            catch { }
        }
        return Binding.DoNothing;
    }
}

2. 修改XAML配置

在资源中定义转换器和波斯日历样式,然后更新DatePicker的绑定与样式:

<Window.Resources>
    <!-- 引用自定义转换器 -->
    <local:GregorianToJalaliConverter x:Key="JalaliConverter" />
    <!-- 配置Calendar使用波斯日历 -->
    <Style x:Key="PersianCalendarStyle" TargetType="{x:Type Calendar}">
        <Setter Property="CalendarIdentifier" Value="PersianCalendar" />
        <Setter Property="FlowDirection" Value="RightToLeft" />
        <Setter Property="Language" Value="fa-IR" />
    </Style>
</Window.Resources>

<!-- 更新后的DatePicker -->
<DatePicker
    Width="140" FlowDirection="RightToLeft"
    BorderThickness="2" Margin="8" Language="fa-IR" 
    materialDesign:HintAssist.Hint="تاریخ پایان"
    Style="{StaticResource MaterialDesignOutlinedDatePicker}"
    CalendarStyle="{StaticResource PersianCalendarStyle}"
    IsReadOnly="True"
    Text="{Binding RelativeSource={RelativeSource Self}, Path=SelectedDate, Converter={StaticResource JalaliConverter}, Mode=TwoWay}" />

关键设置说明

  • PersianCalendarStyle:强制Calendar控件使用波斯日历,解决年份选择面板显示公历的问题,确保整个选择界面的年月都是贾拉利格式。
  • IsReadOnly="True":禁用手动输入,避免用户输入不符合格式的日期,仅通过选择面板操作,保证日期转换的准确性。
  • 文本框绑定转换器:将SelectedDate(公历DateTime)转换为贾拉利日期字符串显示,彻底替换默认的公历转波斯数字格式。

内容的提问来源于stack exchange,提问作者abbas akbarzade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:41:20