Wednesday, January 03, 2007

When ActiveControl Is Not The Active Control

I've created a few container controls in the past by inheriting from the ContainerControl class. This allows the control to host other controls as 'children', and you'd think would do all the right focus management and so on, but you'd be wrong. In fact, the Visual Studio help says "You do not typically inherit directly from the ContainerControl class. Form, UserControl and UpDownBase classes inherit from ContainerControl."

I'm not sure why using ContainerControl as a base class isn't the usual course of action, but I have discovered one reason it's not a good idea - the focus management doesn't work. If you create a custom control inheriting from ContainerControl the host form will always report your custom control as the value of the ActiveControl property, instead of the child control that actually has focus.

In order to properly create a container control you need to implement the IContainerControl interface, and implement code to track the active control and activate it when the appropriate interface members are called. Luckily, this code isn't hard;

//Private member to store the active control in.
private Control activeControl;

bool IContainerControl.ActivateControl(Control active)
{
//If we know the active control, then focus it, otherwise focus the first child control.
bool retVal = false;
if (activeControl != null)
{
activeControl.Focus();
retVal = true;
}
else
{
if (this.Controls.Count > 0)
{
this.Controls[0].Focus();
retVal = true;
}
}
return retVal;
}

Control IContainerControl.ActiveControl
{
get
{
//Return the active control, that we're keeping track of.
return activeControl;
}
set
{
//Keep track of the active control ourselves by storing it in a private member, note that
//that we only allow the active control to be set if it is actually a child of ours.
if (this.Contains(value))
activeControl = value;
}
}

That's all you need to make your container control work. Why this isn't done for us in the ContainerControl (or why it doesn't work), I don't know, but at least the fix is simple.

1 comment:

  1. hi,
    Thanq very much for the Blog it was realy helpful 4r me.

    i have 2 set opacity for inactive form.

    how it can be done?

    ReplyDelete