5

ASP.NET カレンダーは、常に 6 週間の日付を 7x6 グリッドに表示します。私の問題は、対象月の最初の日が必ずしも最初の行に表示されるとは限らないことです...場合によっては、最初の行全体が前月の日付を表示します。それ以外の場合は、最後の行全体に次の行の日付が表示されます。特定の月/年にレンダリングされる 42 日間の範囲を決定するためにカレンダー オブジェクトを照会する信頼できる方法はありますか?

たとえば、2008 年 6 月と 2009 年 2 月を考えてみましょう。

最初の週には前月の日付のみが含まれていることに注意してください http://img371.imageshack.us/img371/2290/datesmq5.png

カレンダーは、「他の月」のすべての日付をグリッドの上部または下部にまとめないようにしようとしているため、対象月の最初の月を 2 行目に配置していると思います。たとえば、2008 年 6 月の表示範囲が 5 月 25 日から 7 月 5 日であることを簡単に判断する方法を探しています。

4

5 に答える 5

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 に答える
5

ASP.NET カレンダー コントロールによって公開されているパブリック メンバーを見ると、この情報がカレンダー コントロールから取得できるとは思えません。

ただし、これに対する「回避策」としていくつかのオプションがありますが、うまくいきません....しかし、それらは機能します。

  1. 最初の週の値を手動で計算できます
  2. 「day render」イベントを処理して、個々の日のバインディングを処理し、最小/最大値を記録できます。

確かにどちらもエレガントではありませんが、私の知る限り、それが唯一の現実的な選択肢です

編集

コメントで議論した後、別のオプションは上記の2番目のオプションの修正版です。基本的に、Day Render が最初に呼び出されたときに、次の 42 日間のデータのブロックを取得します。次に、DayRender への将来の呼び出しで表示する適切な日の値をリストから検索するだけで、毎日の DB ヒットを回避できます。これを行うことは別の「洗練されていない」ソリューションですが、機能し、DB の負荷を少し軽減しますが、アプリケーション側にいくらかのオーバーヘッドが発生します。

ここでは、適切に構造化されたページ レベル プロパティを定義してバインディング イベント中にアイテムを保持することが重要ですが、月が変更された場合などにアイテムが誤って読み込まれないようにすることが重要です。

于 2008-11-04T19:38:43.510 に答える
2

私はこれを自分で調べていて、ここに誘導されました。私は個人的にはオプション 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 に答える