views:

194

answers:

1

I have a Windows Forms custom control which acts like a panel in that it can contain any number of children. The number and type of the child controls are determined at runtime and so I need to work in a generic manner without knowing the exact child controls that might or might not be present.

I want to alter the background color of my panel depending on if the panel contains the focus. So if a child of the panel (or a child of a child of the panel etc...) takes the focus I want to know this so I can update the background color of the custom panel. When the focus shifts away to something that is not in the child hierarchy then I also need to know so I can revert to the original background color.

The Control.ContainsFocus is great for telling me if the panel contains the focus in the child hierarchy but I need to know when there is a change. At the moment I can only come up with the following poor mechanism.

I hook into the GotFocus/LostFocus of each child and each child of each child etc. I also have to hook the ControlAdded/ControlRemoved to ensure I keep in sync with the possible changing child hieararchy. As you can see this might end up with ALOT of event hooks and I suspect there must be an easier approach. Any ideas?

+1  A: 

I'm afraid that's the only option. Winforms has some annoying holes in its api sometimes. I haven't checked but it wouldn't surprise me if ContainsFocus is simply a recursive traversal of the control tree of a container control to see if any control has the focus.

Having a lot of event handlers is not that much of a problem, raising a lot of events which change UI elements is. You could work around this by subsclassing the controls which are addable (but I'm not sure if you have to allow all controls or just a subset) and pass the panel to the control added so the control itself calls into the panel when it gets/loses focus. But that's also a lot of work and the observer-like pattern of having the code in the panel is IMHO easier to do.

Frans Bouma