CheckGroup =>這是繼承自Control並使用OnPaint方法中的GroupBoxRenderer和CheckBoxRenderer的自定義控件的一種方法。它是一個容器,通過改變CheckBoxRenderer的繪製方式來模仿焦點。此代碼摺疊CheckGroup並禁用任何子控件,但可以根據需要刪除其中的一個或兩個。
using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace CoolControls
{
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
public partial class CheckGroup : Control
{
public event EventHandler CheckBoxGotFocus;
public event EventHandler CheckBoxLostFocus;
private int _CheckBoxSideLength;
private Rectangle _CheckBoxBorderRectangle;
private bool _Focused = false;
private bool _Checked;
private CheckBoxState _CheckedState = CheckBoxState.UncheckedNormal;
private int _ExpandedHeight;
[Category("Behavior")]
[Description("Get or set whether the checkbox is checked.")]
public bool Checked
{
get { return _Checked; }
set
{
SetCheckedState(value);
}
}
public CheckGroup()
{
InitializeComponent();
InitControl();
}
private void InitControl()
{
_CheckBoxSideLength = 15;
_Checked = true;
_Focused = false;
_CheckBoxBorderRectangle = new Rectangle(0, 0, _CheckBoxSideLength - 1, _CheckBoxSideLength - 1);
}
private void SetCheckedState(bool pToChecked)
{
_Checked = pToChecked;
if (_Checked)
{
_CheckedState = CheckBoxState.CheckedNormal;
this.Height = _ExpandedHeight;
}
else
{
_CheckedState = CheckBoxState.UncheckedNormal;
this.Height = _CheckBoxSideLength;
}
foreach (Control c in this.Controls)
{
c.Enabled = _Checked;
}
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Graphics g = pe.Graphics;
GroupBoxRenderer.DrawGroupBox(g, ClientRectangle, " " + this.Text, this.Font, this.ForeColor, TextFormatFlags.Left, GroupBoxState.Normal);
CheckBoxRenderer.DrawCheckBox(g, ClientRectangle.Location, _CheckBoxBorderRectangle, "", null, TextFormatFlags.Left, _Focused, _CheckedState);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (_Checked)
{
_ExpandedHeight = this.Size.Height;
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Location.Y <= _CheckBoxSideLength)
{
SetCheckedState(!_Checked);
}
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
_Focused = true;
Invalidate();
CheckBoxGotFocus.Invoke(this, new EventArgs());
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
_Focused = false;
Invalidate();
CheckBoxLostFocus.Invoke(this, new EventArgs());
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Space)
{
SetCheckedState(!_Checked);
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
Invalidate();
}
}
}
我真的不明白這一點,你說你'延伸GroupBox'我認爲這是某種形式的繼承,但如果這樣,爲什麼你必須使用'GroupBoxRenderer'?你自定義的GroupBox的實際基類是什麼?順便說一句,'GroupBox'不支持可聚焦性。我不認爲'GroupBox'需要這樣的功能,你能解釋一下嗎?或者你希望它能夠獲得焦點來處理一些與焦點相關的事件,比如'Enter'和'GotFocus'? –
@KingKing我繼承GroupBox但重寫了OnPaint。我需要自己渲染整個事物,否則GroupBox Text會在摺疊/展開按鈕後面結束(請參閱我添加的圖像)。要明確一點,GroupBox可以通過編程獲得焦點,但由於它是一個靜態控件,它不會通過TabStop機制獲得焦點。 – Steiny