2013-07-11 76 views
2

我已經創建了一個擴展GroupBox的自定義控件。此控件支持摺疊和展開,我使用GroupBoxRenderer和ButtonRenderer使它看起來像一個典型的GroupBox,在角落有一個Button。我已經處理了所有適當的鼠標事件,這些事件有效地使「按鈕」表現得像一個普通的Button。現在我遇到了一個問題,即GroupBox沒有使用TabStop獲得焦點。無論如何,我可以讓我的Collapsable GroupBox從一個TabStop獲得焦點?TabStop和專注於一個GroupBox

我希望我可以用How to set focus to a control after validation in .NET的技巧來設置Enter事件的焦點,但我還沒有想出一個確定何時應該真正獲得焦點的好方法。我大概可以設計一種方法,找到下一個最高和最低的TabIndex(或ChildIndex,如果相同的TabIndex)的兄弟姐妹,然後確定他們是否失去了焦點,但這似乎有點冒失,如果我沒有得到破壞的可能性很高它完全正確。

注:我最初創建用戶控制,但是這不是我想要的各種原因,包括:

  1. 這是不是包含一個按鈕和一個組框控件(它只是恰巧排序看上去如此),它是一個組合框中
  2. 靈活性
  3. 後端代碼和UI之間的耦合
  4. 動態佈局
  5. 跨越需要工具箱支持和丘斯托許多項目共享mising整個控制

這裏的UI和佈局是什麼樣子展開時像: enter image description here

而現在,當它已經坍塌(和具有焦點): enter image description here

+0

我真的不明白這一點,你說你'延伸GroupBox'我認爲這是某種形式的繼承,但如果這樣,爲什麼你必須使用'GroupBoxRenderer'?你自定義的GroupBox的實際基類是什麼?順便說一句,'GroupBox'不支持可聚焦性。我不認爲'GroupBox'需要這樣的功能,你能解釋一下嗎?或者你希望它能夠獲得焦點來處理一些與焦點相關的事件,比如'Enter'和'GotFocus'? –

+0

@KingKing我繼承GroupBox但重寫了OnPaint。我需要自己渲染整個事物,否則GroupBox Text會在摺疊/展開按鈕後面結束(請參閱我添加的圖像)。要明確一點,GroupBox可以通過編程獲得焦點,但由於它是一個靜態控件,它不會通過TabStop機制獲得焦點。 – Steiny

回答

0

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(); 
    } 
} 
}