5

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

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

请注意,第一周仅包含上个月的日期 http://img371.imageshack.us/img371/2290/datesmq5.png

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

4

5 回答 5

5

查看由 ASP.NET 日历控件公开的公共成员,我不认为您可以从日历控件中获取这些信息。

不过,您有一些选择作为“解决方法”,虽然不是很好....但它们会起作用。

  1. 您可以手动计算第一周的值
  2. 您可以处理“day render”事件来处理各个日期的绑定,并记录最小值/最大值。

当然两者都不是优雅的,但 AFAIK 它是唯一真正的选择

编辑

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

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

于 2008-11-04T19:38:43.510 回答
5

我写了几个方法来帮助解决这个问题。只需传入 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;
}
于 2009-05-27T20:14:34.517 回答
2

米切尔,工作完美,谢谢。以公共变量 bool m_FirstDay = false 开始

在 day_render 函数中

if(m_FirstDay == false)
{
    DateTime firstDate;
    DateTime lastDate;

    firstDate = e.Day.Date;
    lastDate = firstDate.AddDays(41);

    m_FirstDay = true;
}

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

于 2009-03-18T18:56:14.577 回答
2

我自己一直在研究这个,并被定向到这里。我个人很想选择选项二,因为替代方案很混乱。Ronnie 的版本很好,但遗憾的是没有考虑不同 FirstDayOfWeeks 的文化。

使用 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)));
}

可悲的是,该功能已经存在,我们只是无法获得它!

于 2009-10-22T16:37:23.087 回答
0

看到这个。

如何删除日历的最后一周

于 2011-05-27T20:41:00.697 回答