[C#][Windows Formsアプリ][MonthCalendar] 表示中の日付範囲を正しく知る

スポンサーリンク

はじめに

Windows Forms の MonthCalendar で「画面にいま見えている日付の最小~最大」を知りたいときは、GetDisplayRange(bool visible) が最短手段です。複数月表示(CalendarDimensions)や前後月の表示が絡む場合でも、実際に見えている境界を安全に取得できます。

説明

GetDisplayRange(true) は、コントロール上に実際に表示されている日付の先頭と末尾(前後月に食い込む表示も含む)を返します。
GetDisplayRange(false) は、現在表示している月単位の先頭日~末日を返すイメージで、前後に見えている“端数の週”に依存しない丸い月境界が得られます。

用途の目安:

・「画面に見えている行だけ集計」→ GetDisplayRange(true)
・「当月(や表示中の複数月)を丸ごと処理」→ GetDisplayRange(false)

サンプルコード(極力短く)

ボタン一発で true/false の違いを確認するミニアプリです。

using System;
using System.Windows.Forms;

class MainForm : Form
{
    MonthCalendar cal = new MonthCalendar { Dock = DockStyle.Fill };
    Button btn = new Button { Text = "表示範囲を確認", Dock = DockStyle.Top };

    public MainForm()
    {
        Text = "MonthCalendar - GetDisplayRange";
        Controls.Add(cal);
        Controls.Add(btn);

        // 例: 2カ月横並びで確認したい場合はコメント解除
        // cal.CalendarDimensions = new System.Drawing.Size(2, 1);

        btn.Click += (s, e) =>
        {
            var vis = cal.GetDisplayRange(true);   // 画面に実際に見えている最小~最大
            var mon = cal.GetDisplayRange(false);  // 月境界での最小~最大(表示中の月を丸ごと)

            MessageBox.Show(
                $"[visible=true]\n{vis.Start:yyyy-MM-dd} ~ {vis.End:yyyy-MM-dd}\n\n" +
                $"[visible=false]\n{mon.Start:yyyy-MM-dd} ~ {mon.End:yyyy-MM-dd}",
                "GetDisplayRange 結果");
        };
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new MainForm());
    }
}

つまづきポイント

1) 思ったより範囲が広い/狭い
true は「実表示基準」、false は「月境界基準」です。前後月の数字が見えている場合、true の開始/終了は当月の1日・末日より外側になり得ます。

2) 複数月表示と組み合わせたとき
CalendarDimensions を広げると、false表示しているすべての月の 1 日~末日をカバーします。true は画面に出ている最初/最後の“日付セル”に一致します。

3) スクロールで範囲がずれる
月送り(ScrollChange)やリサイズ後は、ボタンなどで都度 GetDisplayRange を呼び直して最新の境界を取得しましょう。

まとめ

「いま画面に出ている日付をそのまま処理」なら GetDisplayRange(true)
「当月(または表示中の複数月)を丸ごと扱う」なら GetDisplayRange(false)
この使い分けを覚えておけば、集計や表示最適化の境界管理で迷いません。

Please follow and like us:

コメント

タイトルとURLをコピーしました