如何确定ASP.NET日历显示的整个日期范围?

如何确定ASP.NET日历显示的整个日期范围?,asp.net,calendar,Asp.net,Calendar,ASP.NET日历始终在7x6网格中显示6周的日期。我的问题是目标月的第一天不一定出现在第一行。。。在某些情况下,整个第一行显示上个月的日期。在其他情况下,最后一行显示下一行的日期。 是否有可靠的方法查询calendar对象,以确定特定月份/年份将呈现的42天范围 例如,考虑2008年6月和2月2009日: 我假设日历试图避免将所有“其他月份”日期聚集在网格的顶部或底部,因此将目标月份的第一个日期放在第二行。例如,我正在寻找一种简单的方法来确定2008年6月的显示范围是5月25日至7月5日。查

ASP.NET日历始终在7x6网格中显示6周的日期。我的问题是目标月的第一天不一定出现在第一行。。。在某些情况下,整个第一行显示上个月的日期。在其他情况下,最后一行显示下一行的日期。 是否有可靠的方法查询calendar对象,以确定特定月份/年份将呈现的42天范围

例如,考虑2008年6月和2月2009日:


我假设日历试图避免将所有“其他月份”日期聚集在网格的顶部或底部,因此将目标月份的第一个日期放在第二行。例如,我正在寻找一种简单的方法来确定2008年6月的显示范围是5月25日至7月5日。

查看ASP.NET日历控件公开的公共成员,我不相信这些信息是您可以从日历控件中获得的

你有一些选择作为“变通办法”,虽然不是很好…但它们会起作用

  • 您可以手动计算第一周的值
  • 您可以处理“day render”事件来处理各个日期的绑定,并记录最小/最大值
  • 虽然两者都不优雅,但这是唯一的现实选择

    编辑

    在评论中讨论之后,另一个选项是上面我的第二个选项的修改版本。基本上,在第一次调用Day Render时,获取接下来42天的数据块,然后您可以简单地在列表中搜索适当的Day值,以便在以后调用DayRender时显示,从而避免每天的DB命中。这样做是另一个“不优雅”的解决方案,但它可以工作,并减少了数据库上的一些负载,但在应用程序端引入了一些开销

    在这里,重要的是定义结构良好的页面级属性,以便在绑定事件期间保存项目,但要确保如果一个月发生了变化等,不会错误地加载项目等。

    Mitchel, 非常好,谢谢。 从一个公共变量开始 bool m_FirstDay=false

    在day_渲染函数中

    if(m_FirstDay == false)
    {
        DateTime firstDate;
        DateTime lastDate;
    
        firstDate = e.Day.Date;
        lastDate = firstDate.AddDays(41);
    
        m_FirstDay = true;
    }
    

    然后我有了asp.net日历控件的可见日期范围。再次感谢。

    我写了两个方法来帮助解决这个问题。只需传入Calendar.VisibleDate:

    public static DateTime GetFirstDateOfMonth(DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1);
    }
    
    public static DateTime GetFirstDisplayedDate(DateTime date)
    {
        date = GetFirstDateOfMonth(date);
        return date.DayOfWeek == DayOfWeek.Sunday ? date.AddDays(-7) : date.AddDays((int)date.DayOfWeek * -1);
    }
    
    public static List<DateTime> GetDisplayedDates(DateTime date)
    {
        date = GetFirstDisplayedDate(date);
    
        List<DateTime> dates = new List<DateTime>();
        for (int i = 0; i < 42; i++)
        {
            dates.Add(date.AddDays(i));
        }
    
        return dates;
    }
    
    publicstaticdatetime GetFirstDateOfMonth(DateTime日期)
    {
    返回新的日期时间(date.Year,date.Month,1);
    }
    公共静态日期时间GetFirstDisplayedDate(日期时间日期)
    {
    日期=GetFirstDateOfMonth(日期);
    return date.DayOfWeek==DayOfWeek.Sunday?date.AddDays(-7):date.AddDays((int)date.DayOfWeek*-1);
    }
    公共静态列表GetDisplayedDates(日期时间日期)
    {
    日期=GetFirstDisplayedDate(日期);
    列表日期=新列表();
    对于(int i=0;i<42;i++)
    {
    日期。添加(日期。添加天数(i));
    }
    返回日期;
    }
    
    我自己也在研究这个问题,并直接转到这里。我个人倾向于选择第二种,因为另一种选择很混乱。罗尼的版本很好,但不幸的是,它没有考虑到不同文化的第一天

    使用Reflector,我们可以看到它是如何在内部完成的:

    
        ...
        DateTime visibleDate = this.EffectiveVisibleDate();
        DateTime firstDay = this.FirstCalendarDay(visibleDate);
        ...
    
    private System.Globalization.Calendar threadCalendar = 
        DateTimeFormatInfo.CurrentInfo.Calendar;
    
    private DateTime EffectiveVisibleDate()
    {
        DateTime visibleDate = this.VisibleDate;
        if (visibleDate.Equals(DateTime.MinValue))
        {
            visibleDate = this.TodaysDate;
        }
        if (this.IsMinSupportedYearMonth(visibleDate))
        {
            return this.minSupportedDate;
        }
        return this.threadCalendar.AddDays(visibleDate, 
            -(this.threadCalendar.GetDayOfMonth(visibleDate) - 1));
    }
    
    
    private DateTime FirstCalendarDay(DateTime visibleDate)
    {
        DateTime date = visibleDate;
        if (this.IsMinSupportedYearMonth(date))
        {
            return date;
        }
        int num = ((int) 
           this.threadCalendar.GetDayOfWeek(date)) - this.NumericFirstDayOfWeek();
        if (num <= 0)
        {
            num += 7;
        }
        return this.threadCalendar.AddDays(date, -num);
    }
    
    private int NumericFirstDayOfWeek()
    {
        if (this.FirstDayOfWeek != FirstDayOfWeek.Default)
        {
            return (int) this.FirstDayOfWeek;
        }
        return (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;
    }
    
    private bool IsMinSupportedYearMonth(DateTime date)
    {
        return this.IsTheSameYearMonth(this.minSupportedDate, date);
    }
    
    private bool IsTheSameYearMonth(DateTime date1, DateTime date2)
    {
        return (((this.threadCalendar.GetEra(date1) == 
                       this.threadCalendar.GetEra(date2)) &&
              (this.threadCalendar.GetYear(date1) == 
                       this.threadCalendar.GetYear(date2))) &&
              (this.threadCalendar.GetMonth(date1) ==
                       this.threadCalendar.GetMonth(date2)));
    }
    
    
    
    ...
    DateTime visibleDate=此.EffectiveVisibleDate();
    DateTime firstDay=此.FirstCalendarDay(visibleDate);
    ...
    private System.Globalization.Calendar线程日历=
    DateTimeFormatInfo.CurrentInfo.Calendar;
    private DateTime EffectiveVisibleDate()
    {
    DateTime visibleDate=this.visibleDate;
    if(visibleDate.Equals(DateTime.MinValue))
    {
    visibleDate=this.TodaysDate;
    }
    如果(此.IsImportedeArmonth(visibleDate))
    {
    返回此.minSupportedDate;
    }
    返回此.threadCalendar.AddDays(visibleDate,
    -(this.threadCalendar.GetDayOfMonth(visibleDate)-1);
    }
    private DateTime FirstCalendarDay(DateTime visibleDate)
    {
    DateTime日期=visibleDate;
    如果(本文件不支持日期))
    {
    返回日期;
    }
    int num=((int)
    this.threadCalendar.GetDayOfWeek(date))-this.NumericFirstDayOfWeek();
    如果(num看到这个


    问题是,在我从数据层获取数据之前,我需要知道将要渲染的范围,因此使用DayRender不是一个选项。我可能会做#1,尽管我讨厌尝试对必要的算法进行反向工程的想法……似乎非常容易出错。不过,谢谢!有什么理由你不能在dayr上调用dB吗ender是否要获取您所需的准确数据?@Mitchel:这将导致每天单独命中一个DB。我宁愿确定将显示的日期范围,然后在一个DB调用中获取所有数据,不多也不少。@Mitchel:除非您建议我使用第一个DayRender调用来获取整个范围的数据?我同意ess我可以确定这是第一次渲染调用,添加42天,然后获取数据…这不是完美的,但它有潜力。你可以添加这一点作为答案吗?@seth:将添加该选项。尽管在我创建日历的所有测试中,我已经创建了很多,但多个DB点击的开销,尽管有点影响,例如由于实现的简单性,这是一个总体上可行的解决方案。我喜欢这个解决方案,只是这个解决方案没有考虑到不同的文化。请参阅[link]以获取给定GetFirstDateOfMonth的一周的第一个日期。