2013-07-11 3 views
2

Я создал настраиваемый элемент управления, который расширяет GroupBox. Этот элемент управления поддерживает свертывание и расширение, и я использую GroupBoxRenderer и ButtonRenderer, чтобы он выглядел как типичный GroupBox с кнопкой в ​​углу. Я обработал все соответствующие события мыши, которые эффективно заставляют «кнопку» вести себя и выглядеть как обычная кнопка. Теперь я столкнулся с проблемой, когда GroupBox не получает фокуса с помощью TabStop. Есть ли в любом случае, что я могу получить мой Collapsable GroupBox для получения фокуса с TabStop?TabStop и Focus на GroupBox

Я надеялся, что смогу использовать трюк от How to set focus to a control after validation in .NET, чтобы установить фокус в событии Enter, но у меня не было хорошего способа определить, когда он должен фактически получить фокус. Возможно, я мог бы найти способ найти братьев и сестер со следующим самым высоким и самым низким TabIndex (или ChildIndex, если тот же TabIndex), а затем определить, потеряли ли они фокус, но это кажется немного взломанным и имеет высокий шанс взлома, если я не получу это точно.

Примечание: Я изначально создать пользовательский элемент управления, но это не то, что я хотел по разным причинам, включая:

  1. Это не элемент управления, который содержит кнопку и GroupBox (это просто так случается, вроде выглядеть именно так), это Groupbox
  2. Гибкость
  3. Связь между бэкэнд код и UI
  4. Динамическая компоновка
  5. Shared во многих проектах, требующих поддержки Toolbox и Custo mising интерфейс и расположение всего элемента управления

Вот как это выглядит в развернутом: enter image description here

И теперь, когда это было свернуто (и имеет фокус): enter image description here

+0

Я не получаю это, вы сказали, что 'расширяет GroupBox' который я думаю, это своего рода наследство, но если это так, почему вы должны использовать' GroupBoxRenderer'? Каков фактический базовый класс вашего пользовательского «GroupBox»? BTW, «GroupBox» не поддерживает фокусируемость. Я не думаю, что «GroupBox» нуждается в такой функции, не могли бы вы объяснить об этом больше? Или вы хотите, чтобы он мог получать фокус, чтобы обрабатывать некоторые связанные с фокусом события, такие как «Enter» и «GotFocus»? –

+0

@KingKing Я наследую GroupBox, но переопределяю OnPaint. Мне нужно сделать все, иначе текст GroupBox окажется за кнопкой collapse/expand (см. Изображения, которые я добавил). Чтобы быть понятным, GroupBox может получать фокус программно, но поскольку он является статическим контролем, он не получит фокуса через механизм TabStop. – Steiny

ответ

0

CheckGroup => Вот подход к настраиваемому элементу управления, который наследуется от элемента управления и использует метод GroupBoxRenderer и CheckBoxRenderer в методе OnPaint. Это контейнер, который имитирует фокус, изменяя способ рисования 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(); 
    } 
} 
}