概要

Windows Forms の UltraCalendarCombo コントロールで、カレンダー上の日付セルにフォーカスが当たった際に表示される フォーカス枠 を、DrawFilterIUIElementDrawFilter)を使ってカスタマイズする方法について説明します。色・太さ・線種 などを自由に変更できます。

対象コントロール

  • Infragistics Windows FormsUltraCalendarCombo

問題

UltraCalendarCombo のカレンダーでは、日付セルにフォーカスが当たると既定で 赤い点線のフォーカス枠 が表示されます。この枠の 色・太さ・線種 を変更したい場合、プロパティによる直接指定の手段がありません。

解説

IUIElementDrawFilter を実装する

IUIElementDrawFilter インターフェイスを実装したクラスを作成し、DrawPhase.BeforeDrawFocus フェーズで独自の枠線を描画します。DrawElement メソッドで true を返すことで既定の描画(点線)をスキップし、任意の Pen で枠線を描き替えます。

手順は以下のとおりです。

  1. IUIElementDrawFilter を実装したクラスを作成する
  2. GetPhasesToFilterDrawPhase.BeforeDrawFocus を返す
  3. DrawElementdrawPhase == DrawPhase.BeforeDrawFocus のときに Graphics.DrawRectangle でカスタム枠線を描画し、true を返す
  4. UltraCalendarCombo.DrawFilter にインスタンスを設定する

サンプルコード

DrawFilter 実装クラス

internal class ActivationObjectDrawFilter : IUIElementDrawFilter
{
    private readonly Pen _theFocusPen;
    private readonly int _xOffset;
    private readonly int _yOffset;
    private readonly int _wOffset;
    private readonly int _hOffset;

    public ActivationObjectDrawFilter(Pen theFocusPen, int xOffset, int yOffset, int wOffset, int hOffset)
    {
        _theFocusPen = theFocusPen;
        _xOffset = xOffset;
        _yOffset = yOffset;
        _wOffset = wOffset;
        _hOffset = hOffset;
    }

    public bool DrawElement(DrawPhase drawPhase, ref UIElementDrawParams drawParams)
    {
        if (drawPhase == DrawPhase.BeforeDrawFocus)
        {
            Rectangle regularRect = drawParams.Element.Rect;
            Rectangle clippedRect = drawParams.Element.ClipRect;
            Rectangle focusRect;

            if (clippedRect.Width < regularRect.Width || clippedRect.Height < regularRect.Height)
                focusRect = clippedRect;
            else
                focusRect = regularRect;

            focusRect = new Rectangle(
                focusRect.X + _xOffset,
                focusRect.Y + _yOffset,
                focusRect.Width + _wOffset,
                focusRect.Height + _hOffset);

            drawParams.Graphics.DrawRectangle(_theFocusPen, focusRect);
            return true;  // 既定描画をスキップ
        }
        return false;
    }

    public DrawPhase GetPhasesToFilter(ref UIElementDrawParams drawParams)
    {
        return DrawPhase.BeforeDrawFocus;
    }
}

フォームへの適用

private void Form1_Load(object sender, EventArgs e)
{
    var focusPen = new Pen(Color.HotPink, 2f)
    {
        DashStyle = DashStyle.Solid
    };

    ultraCalendarCombo1.DrawFilter = new ActivationObjectDrawFilter(
        focusPen,
        1,   // X オフセット
        1,   // Y オフセット
        -3,  // 幅オフセット
        -3   // 高さオフセット
    );
}

まとめ

設定項目内容
IUIElementDrawFilter.GetPhasesToFilterDrawPhase.BeforeDrawFocus を返してフォーカス描画フェーズのみをフィルタ対象にする
IUIElementDrawFilter.DrawElementBeforeDrawFocus フェーズで Graphics.DrawRectangle を呼び出し、true を返して既定の点線描画をスキップする
UltraCalendarCombo.DrawFilter実装したフィルタのインスタンスを設定する

製品について

Ultimate UI for Windows Forms