|
Share Controls Between WinForms
Pass user controls from Windows Form to Windows Form to dramatically rearrange your GUI layout without needing to reinitialize the shared user controls and more.
by Michael Kennedy
October 11, 2004
Technology Toolbox: VB.NET, C#, Windows Forms
You can use various techniques for working with user controls in .NET that involve complex and time-intensive rendering. The primary one I present gives you the capability to pass a user control from Windows Form to Windows Form so you can rearrange your graphical user interface (GUI) layout dramatically without needing to reinitialize the shared user control.
Sometimes sharing a user control makes a lot of sense. However, most of the time, that's not the case. I state this plainly now to avoid any confusion about what I'm advocating here. When this technique is useful, it's extremely useful. However, use it only when it's necessary because most of the time it makes your applications unnecessarily complex.
The benefit of passing user controls between Windows Forms (or control containers of any sort, for that matter) is that the passed control retains its state. Consider a control that draws complex scenes. When you want to display the same information using the same type of control on another Windows Form, this control could take any amount of time to reinitialize. For the sake of this discussion, suppose you have a scene that takes 15 seconds to render. If you have a scene drawn on a given Windows Form and want to load a second Windows Form with the same scene, this form could take another 15 seconds just to load.
Alternatively, you could pass the existing control to the second Windows Form if the original Windows Form doesn't need it. This allows the application to display the second Windows Form immediately with the control in exactly the same state it was when it was on the first Windows Form.
I've provided a sample app and Visual Studio solution with this article that demonstrates when passing user controls between Windows Forms is useful. It includes a control that takes a long time to render. In fact, this screenshot took about 12 hours to render (see Figure 1). It could have been drawn much faster, but the idea behind the sample app is to show you a control that takes long enough to initialize that it can benefit from the techniques I cover in this article.
Given the actual implementation for passing controls between Windows Forms is simple, I've created a UI that is more flashy and fun than Windows UIs typically are. It has brighter colors and includes slightly unconventional UI elements such as hyperlinks for a flat menu system and a link (with the text >>>) to pop the control on and off the main Windows Form. If you don't like the UI, please look past it. It has nothing to do with the main concepts I'm presenting.
Pass Controls Between Containers
I use these techniques in the sample application and code: passing user controls between control containers, dynamic control manipulation, double-buffered rendering in GDI+, and animating GDI+.
You can pass user controls between Windows Forms just as easily with control containers such as Panels, TabPages, and GroupBoxes, but given passing controls between different Windows Forms is an extreme case, it's the one I'll cover.
It might or might not be obvious to you that you can pass user controls between Windows Forms. I must admit it caught me by surprise. I thought originally that once a control was created in its parent, it had to stay there. One day I was feeling particularly rebellious and tried to move a control from one Windows Form to another anyway. I was pleasantly surprised to find out that it worked perfectly.
Now those of you who were not surprised might wonder why I thought this. A main reason is that there are analogous issues when accessing controls across threads. Certain controls can only be accessed directly from the thread that created them. So in a multithreaded application, you can't do something as simple as add a control created on a worker thread to the Form.Controls collection. If you do, you get this error: "An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll. Additional information: Controls created on one thread cannot be parented to a control on a different thread."
Back to top
|