はじめに
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)。
この使い分けを覚えておけば、集計や表示最適化の境界管理で迷いません。
コメント