I'm experiencing some strange behavior. Let me try to explain, I stripped my code down to the bare minimum and I'm still having the problem. So first of all, I'm using VS2013 with .NET 4.0 and I'm on Windows 8.1.
So I have a custom UserControl
with a TextBox
that's being used through a ToolStripControlHost
, if I focus on this textbox and hit TAB, it only cycles through the controls to the LEFT of this textbox. If I have it focused and hit SHIFT+TAB, it cycles through the buttons to the right of it.
So this is an example of my form. The textbox in the middle is a custom control. My code (as simplified as possible) looks like:
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripTestControl : ToolStripControlHost
{
public ToolStripTestControl() : this(new TestControl()) { }
public ToolStripTestControl(Control c) : base(c) { }
}
public class TestControl : UserControl
{
private TextBox _textBox = new TextBox();
public TestControl()
{
_textBox.Dock = DockStyle.Fill;
this.Controls.Add(_textBox);
}
protected override Size DefaultMinimumSize { get { return new Size(100, 22); } }
}
Simply creating a new WinForms (.NET4) project and following these steps will allow you to replicate the problem:
Once running...
Does anyone know what the problem is - or how I can fix this? I've been tearing my hair out all day trying to fix this. I finally stripped my code down and I can't seem to get it to work. I even tried overriding much of the OnEnter
/OnGotFocus
functionality and doing it myself, but that became a nightmare.
Thanks!
Update1: So a few extra tid-bits.
If I change the custom control to inherit from TextBox instead of UserControl, tabbing/focus works as expected.
If I change it to be a Control
instead of a UserControl
the tabbing works fine, as well, however the focus never gets inside my inner TextBox - the focus seems to be lost (or presumably on the outer parent control but not being passed down to the inner TextBox).
I do see a MS Connect item added that describes this problem from 2009, but this link only seems to work if I'm NOT logged in to Microsoft Connect. Which means, I can't vote on it or comment... http://connect.microsoft.com/VisualStudio/feedback/details/472592/tab-cycling-through-controls-with-usercontrol-on-toolstrip-doesnt-perform-as-expected
The .NET 2.0 ToolStripItem classes have been a major bug factory. They are window-less controls, but reproducing the exact behavior of a Windows window isn't that easy. There is an enormous amount of code underneath, most of it internal so you can't tinker with it. And with quirks when they don't emulate the behavior of a window perfectly. You could call them "airspace" issues, pretty similar to the kind of problems that WPF has.
The airspace issue here is focus, entirely unambiguous for a true window but it needs to be faked for a ToolStripItem. It is actually the item's parent that has the focus, it needs to be emulated for the item. It is the transition that bytes, ToolStrip expects a window-based control to have a reliable Focus property.
Trouble is, your custom host doesn't. It is the inner control that has the focus. This could arguably be blamed on an omission in the ToolStripControlHost class. Probably. The trouble with emulating a window, there's never enough code :)
Anyhoo, fix your problem by adding this sliver of code to your host:
public override bool Focused {
get { return _textBox.Focused; }
}