[C#][Windows Formsアプリ][MonthCalendar] クリック位置が「どこ」かを判定する

スポンサーリンク

はじめに

Windows Forms の MonthCalendar は、HitTest(Point) でマウス座標から「どの部位(セル/ボタン/タイトル/今日はココ など)をクリックしたか」を判定できます。日付セルだけでなく、前月/翌月ボタンや曜日ヘッダー、タイトル帯なども識別できるため、部位ごとに挙動を変える実装が簡単になります。

説明

HitTest(Point)MonthCalendar.HitTestInfo を返します。主なプロパティは以下の通りです。

HitArea:クリック部位(Date / NextMonthButton / PrevMonthButton / CalendarHeader / Title / TodayLink など)
Time:部位が Date のとき、その日付が入る(それ以外は DateTime.MinValue

この戻り値を使って、日付セルなら詳細ポップアップ前後月ボタンならログタイトルクリックで並び替え、など柔軟に分岐できます。

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

マウスダウン位置の部位と日付をトースト表示するだけの最小例です。

using System;
using System.Windows.Forms;

class MainForm : Form
{
    MonthCalendar cal = new MonthCalendar { Dock = DockStyle.Fill };

    public MainForm()
    {
        Text = "MonthCalendar - HitTest(Point)";
        Controls.Add(cal);
        cal.MouseDown += (s, e) =<
        {
            var hit = cal.HitTest(e.Location);
            string msg = hit.HitArea.ToString();
            if (hit.HitArea == MonthCalendar.HitArea.Date)
                msg += $" : {hit.Time:yyyy-MM-dd}";
            // 例: 前後月ボタンやTodayLinkなども判別可
            // if (hit.HitArea == MonthCalendar.HitArea.NextMonthButton) { ... }

            // さっと確認できる簡易表示
            var tip = new ToolTip();
            tip.Show(msg, cal, e.Location, 1500);
        };
    }

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

つまづきポイント

1) 日付が取れない
TimeHitArea == Date のときだけ有効です。ヘッダーやボタンでは DateTime.MinValue になります。

2) 座標はクライアント座標で渡す
HitTest に渡すのは MonthCalendarクライアント座標です。マウスイベント(MouseDown など)の e.Location をそのまま使えばOK。

3) 複数月表示でも判定できる?
はい。CalendarDimensions で複数月表示でも、クリック位置に対応する正しい HitArea/Time が返ります。

まとめ

HitTest(Point) を使えば、「どこが押されたか」をピンポイントに把握できます。日付セルとその他の部位を分けて処理するだけで、操作感のよいカレンダー連携 UI を短いコードで実現できます。

Please follow and like us:

コメント

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