views:

211

answers:

1

I have a custom control: it's managed code, which subclasses System.Windows.Forms.Control.

I want to add things like edit boxes, selection lists, combo boxes, radio buttons and so on to places on this control. An easy way to do this is to simply add instances of these classes to the Controls collection, so that they become child controls.

Adding them as child controls might create some subtle problems, for example:

  • http://stackoverflow.com/questions/552326/ie-6-select-controlscombo-box-over-menu

  • I have scrollbars on my control which appear to scroll the contents of the control (the contents are bigger than the control itself); when a child control is near the edge of the screen then I'd like to half-display (i.e. clip) that child (i.e. to have half of it located off the edge of the physical screen), but a true child control cannot be located outside the border of its parent.

  • Are there other potential problems?

When I use IE7 to display http://www.tizag.com/htmlT/htmlselect.php (for example), which contains combo boxes etc., and when I then use Spy++ to spy on IE7 when I'm doing that, I see only a single Window/control instance with no children (whose class name is "Internet Explorer_Server").

I'm guessing this means that in IE7, the functionality to render a combo box is built in to the IE7 control itself, and that IE7 does not use standard controls as child controls.

Questions:

  • Is it better to reuse standard controls as children of a custom control, or, to reimplement the functionality of standard controls within a custom control itself?
  • Do you have any caveats (warnings) to share, related to either scenario?
  • If I wanted to reimplement the functionality of standard controls within a custom control, do you know of any existing code (which implements this functionality) that I could re-use?

If such code already exists, I don't know how to search for it (my searches find, for example, owner-draw combo boxes, and extensions to standard combo boxes): perhaps few people reimplement the standard controls from scratch?


Edit

I found a semi-related question: http://stackoverflow.com/questions/2874/how-to-render-a-control-to-look-like-combobox-with-visual-styles-enabled

+1  A: 

Yes, Internet Explorer draws the controls using the Windows theming APIs. You can do this too using the types defined in the System.Windows.Forms.VisualStyles namespace.

The IE team did this to avoid performance problems of having so many controls, each receiving window messages, on screen at once. For example, looking at this StackOverflow.com page, I see 30-40 link label controls, 10 buttons or so, 20+ labels, etc.

It should be noted the Zune software, which is .NET managed code, also uses custom controls; if you try to use Spy++ on any of the controls, you'll see they aren't real Win32 controls. You may use Reflector on the Zune software to see exactly what they're doing. If I recall right, they're using a custom managed UI framework that's included in the Zune software.

As far as rewriting these controls from scratch, I think there's a ton of work to be done. It sounds easier than it really would be.

Judah Himango
Thank you very much. I didn't know that the ControlPaint and VisualStyleRenderer classes existed, and they look like they'd be a great help with the details of painting if I were reimplementing the controls' functionality inside my custom control.You said that "rewriting these controls from scratch [would be] a ton of work", but don't these classes exist in order to help reimplement these controls (as if rewriting these controls by using these classes is a normal and expected thing to do)?
ChrisW
These classes exist to make painting these controls with proper theming easier. Actually implementing their functionality is much more than just painting them. It's certainly possible (IE, Zune and others do this), but it's a lot of work.
Judah Himango
Thanks again. I suspect that the only one that's a lot of work is the edit box. Incidentally, VisualRender is wrapped by other classes such as TextBoxRenderer.
ChrisW
Cool. Let us know how it works out for you.
Judah Himango
So far I have two problems: one is that I don't know how much to offset the text when a button a pressed, and the other is that "(new VisualStyleRenderer(VisualStyleElement.Button.PushButton.Normal)).GetMargins(graphics, MarginProperty.CaptionMargins);" causes an access violation exception so I don't know how much padding there should be between the text and the edge of a button. I've implemented other controls though (checkbox, radio button, and edit box).
ChrisW
Cause of the access violation in GetMargins is said to be a bug in the GetMargins implementation; using the work-around given in http://code.google.com/p/szotar/source/browse/trunk/Client/Szotar.WindowsForms/Base/NativeToolStripRenderer.cs (i.e. P/Invoke to the GetThemeMargins) works Ok. Until now I've been able to avoid doing P/Invokes, though, so instead of doing P/Invoke now I think I'll use a hard-coded Padding value.
ChrisW
Cool. Keep us informed. Is this a library you're planning on publicly releasing? Seems like the perf of such a toolkit would be far more lightweight than the hefty WinForms.
Judah Himango
"Keep us informed" -- I've done it. The bigger ones were select (because of the drop down) and textarea (because of the text-editing and line wrapping). Is there anything in particular you'd like to know about it?
ChrisW
I've released it, as a control: see the [ModelText HTML Editor](http://www.modeltext.com/html/). Although its main purpose is a WYSIWYM editor, but it also handles [Web Form Controls](http://www.modeltext.com/html/user-interfaces.aspx#form_controls).
ChrisW
Wow! Awesome. This would have been very useful on my last project. I'll keep it bookmarked.
Judah Himango