Click here to Skip to main content
Click here to Skip to main content

Simple Popup Control

By , 26 Mar 2013
 
Sample application using a custom popup control:

Custom popup control

Another application using a custom tooltip...

Custom tooltip

... and a more complex popup that can be resized:

Resizable popup

Tracking popup opening below the specified part of a control:

Tracking popup

Cascade of popup controls:

Cascade of popup controls

Introduction

Popup windows are everywhere. Each tooltip is a popup window; each combobox has its popup list; many advertisements are also shown in popup windows.

How to Create a Popup Control in .NET?

At first, we might choose the Form class as a base class for our popup control. Unfortunately, it is a bad choice because when we show our popup form, the parent form loses its focus. A popup window should not cause that. Luckily, there is a class that does not cause loss of focus. We can use it as a base class for our popup control. It is the ToolStripDropDown class.

How to Use the ToolStripDropDown Class?

This would be the simplest way, without deriving from that class:

ToolStripDropDown popup = new ToolStripDropDown();
popup.Margin = Padding.Empty;
popup.Padding = Padding.Empty;
ToolStripControlHost host = new ToolStripControlHost(content);
host.Margin = Padding.Empty;
host.Padding = Padding.Empty;
popup.Items.Add(host);
popup.Show(parentForm, location);

In this case, content is a control we want to show in a popup window. Of course, we have to remember to later dispose the popup window and its contents.

Popup Class

I wrote a Popup class that derives from ToolStripDropDown and simplifies the creating and managing of popup windows. The class calculates by itself where it should "pop" on the screen. It also disposes itself immediately after disposing the content control. To show a popup with a button, for example, we could write:

new Popup(new Button()).Show(someControl);

Here, someControl would be a control below which we want to show our popup.

Popup Resizing

To enable resizing for your popup, you must set the Resizable property to true and add the following code into your content control class:

protected override void WndProc(ref Message m)
{
    if ((Parent as Popup).ProcessResizing(ref m)) return;
    base.WndProc(ref m);
}

You also have to set the ResizeRedraw property of the content control to true.

Important!

To specify the minimum and maximum size of the content control, please use the following properties:

  • content.MinimumSize and content.MaximumSize only inside the constructor of the content control
  • popup.MinimumSize and popup.MaximumSize elsewhere

ComboBox Class

The System.Windows.Forms.ComboBox class behaves in a strange way when it is on a popup control. It closes the popup control when the user clicks on a part of the combobox's dropdown that sticks out of a popup. So, I have created a PopupControl.ComboBox class that behaves properly.

PopupComboBox Class

This is a base class for comboboxes that can have a custom dropdown attached.

Animation Support

Animation is enabled by default. To change it, set the AnimationDuration, HidingAnimation, and ShowingAnimation properties.

Popup Members

Properties

  • AcceptAlt — Gets or sets a value indicating whether pressing the Alt key should close the popup.
  • AnimationDuration — Determines the duration of the animation.
  • Content — Gets the content of the popup.
  • FocusOnOpen — Gets or sets a value indicating whether the content should receive the focus after the popup has been opened.
  • HidingAnimation — Determines which animation to use while hiding the popup window.
  • MaximumSize — Gets or sets a maximum size of the popup.
  • MinimumSize — Gets or sets a minimum size of the popup.
  • NonInteractive — Gets or sets a value indicating whether the popup acts like a transparent windows; e.g., it cannot be clicked (note — it does not affect child controls).
  • Resizable — Gets or sets a value indicating whether the popup is resizable.
  • ShowingAnimation — Determines which animation to use while showing the popup window.

Constructor

  • Popup(Control content) — Initializes a new instance of the Popup class.

Methods

  • void PaintSizeGrip(PaintEventArgs e) — Paints the sizing grip.
  • bool ProcessResizing(ref Message m) — Processes the resizing messages.
  • void Show(Control control) — Shows the popup window below the specified control.
  • void Show(Control control, Rectangle area) — Shows the popup window below the specified area of the specified control.

TODO

  • Base class for custom tooltips.
  • Office 2007-like tooltip class.

History

  • 1.5 (20.10.2010) — Important! This is the last “standalone” version of the control. The next version is included in a new project hosted at CodePlex.
    • Added the NonInteractive property to the Popup class.
    • Fixed resizing on DualView/multi monitor systems.
    • Popup is now always shown on top of other windows (previously the popup could be shown below its parent during the animation process).
    • PopupComboBox didn’t properly set focus to its dropdown on Windows 7.
    • Improved compatibility with Mono.
    • Uses C# 3.0 syntax (auto-properties, lambdas).
    • Signed binaries for both .NET 2.0 and .NET 4.0 are available.
    • Solution upgraded to the Visual C# 2010 format.
    • License changed to LGPL 3.0.
  • 1.4 (16.01.2009)
    • Added the DroppedDown property, and the DropDown, DropDownClosed events to the PopupComboBox class.
    • Fixed resizing of a popup when the MaximumSize property of the content control is not set.
  • 1.3.1 (20.09.2008)
    • Tab-key properly transfers the focus between controls contained in a popup window.
    • Minor bugs fixed.
  • 1.3 (04.05.2008)
    • Added the AnimationDuration, HidingAnimation, and ShowingAnimation properties.
    • Removed the UseFadeEffect property.
    • Popup control can animate now even when the FocusOnOpen property is set to false.
  • 1.2.5 (24.01.2008)
    • Fixed “Alt+F4” bug.
    • Fixed drawing the sizing grip.
    • Minor bugs fixed.
  • 1.2 (24.07.2007)
    • Added animation support.
    • Added AcceptAlt property.
    • Clicking on the non-client area bug fixed.
    • Minor bugs fixed.
  • 1.1 (05.07.2007)
    • Added XML documentation.
    • "Fixed" the ComboBox class, so it can be used inside a popup.
    • Added base class for a combobox that can have a custom dropdown, PopupComboBox.
    • The sizing grip is automatically drawn if a popup is resizable.
    • Added support for a minimum and maximum size of a resizable popup.
    • Minor bugs fixed.
  • 1.0
    • 08.06.2007 – Added resizing support and capability for using cascading pop-ups.
    • 06.02.2007 – Added keyboard and custom region support, and the ShowForControl method name changed to Show.
    • 03.02.2007 – First version.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

About the Author

Lukasz Swiatkowski
Software Developer
Poland Poland
Member
I am a graduate of Wroclaw University of Technology, Poland.
 
My interests: reading, programming, drawing, Japan, yoga, tai-chi.
 
My website: www.lukesw.net

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionDesigner Disposememberzigygonzalez25 Mar '13 - 6:51 
Hi, please tell us why you use this code in designer:
 
if (Content != null)
{
 System.Windows.Forms.Control _content = Content;
 Content = null;
 _content.Dispose();
}

AnswerRe: Designer DisposememberLukasz Swiatkowski26 Mar '13 - 22:43 
I believe it was for better compatibility with Mono.
My website: www.lukesw.net

QuestionHow can I move popup control?memberminhvc3 Dec '12 - 21:33 
I want to move popup control, when I click and hold left mouse button, I move mouse and the popup control move new position.
AnswerRe: How can I move popup control?memberLukasz Swiatkowski26 Mar '13 - 22:40 
It’s not possible now, but it’s interesting feature I might add in next version.
My website: www.lukesw.net

QuestionCodeplex URL?memberDan Neely7 Nov '12 - 5:30 
You've stated that future work on the control will be done on codeplex; but I can't find it there.
Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason?
Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful?
--Zachris Topelius
 

Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies.
-- Sarah Hoyt

AnswerRe: Codeplex URL?memberLukasz Swiatkowski26 Mar '13 - 22:39 
I’ve updated the article with the project link Smile | :)
My website: www.lukesw.net

QuestionHow to set custom display locations?membervighnu16 Aug '12 - 0:50 
Hi sir,
This is a really cool utility.I was wondering how to have custom display locations ?
eg: centre of the screen or centre of the control or at this particular co-ordinates.
AnswerRe: How to set custom display locations?memberLukasz Swiatkowski16 Sep '12 - 22:52 
You can add your own custom Show method to set preferred location Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

AnswerTextbox focus FIXmemberSteveStokes3 Jul '12 - 5:43 
Ok, so on stackoverflow, there is this solution to prevent the FIRST click into the control needing a double click:
 
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (NativeMethods.WM_REFLECT + NativeMethods.WM_COMMAND))
            {
                if (NativeMethods.HIWORD(m.WParam) == NativeMethods.CBN_DROPDOWN)
                {
                    // Blocks a redisplay when the user closes the control by clicking 
                    // on the combobox.
                    TimeSpan TimeSpan = DateTime.Now.Subtract(dropDown.LastClosedTimeStamp);
                    if (TimeSpan.TotalMilliseconds > 500)
                    { BeginInvoke(new MethodInvoker(ShowDropDown)); }
                    return;
                }
            }
            base.WndProc(ref m);
        }
 
The above solution is correct to fix the first click issue, where it required two clicks to enter the list of checkboxes, however, this introduces a new issue when you click on the control to exit its focus, it retains the focus and you must double click to go to another control. I was able to fix this with the following code:
 
In CheckBoxComboBox.cs add the following override:
 
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            this.Parent.Focus();
        }
 
With both of these solutions, it will not hold focus on either click event (enter, or exit).
QuestionRe: Textbox focus FIXmemberranzhifa23 Sep '12 - 16:36 
<pre lang="CSS"></<pre>
pre>
<pre><pre lang=<small></</code>strike></small>"c++">

BugTextBox FocusmemberMember 37814937 May '12 - 4:50 
Hi,
 
your Popup Control works quite good, but has a problem with Textbox controls. After showing the popup the Textbox lost its focus.
 
Is there a way to solve the problem?
 
Thanks!
GeneralRe: TextBox FocusmemberMember 15052874 Jun '12 - 13:58 
I found a way to do this, well at least for me.
Set the FocusOnOpen property to false and do this when you want to show the popup
 
_searchPopup.AutoClose = false;
_searchPopup.Show(uiTextBox);
_searchPopup.AutoClose = true;

QuestionVB-Version? [modified]memberdherrmann23 Jan '12 - 11:19 
Hi Lukasz,
 
have you thought about the VB-Version? It would be great!
 
Because I can't use the MoreComplexPopup.dll under VB...
 
Regards-
Dietrich

modified 24 Jan '12 - 6:53.

QuestionBon travailmemberAMINE ARAFY17 Jan '12 - 1:39 
Thanks from morocco Wink | ;)
GeneralMy vote of 5memberMuhammad Dehghan8 Jan '12 - 21:11 
Really helpful control. Also very well designed.
GeneralRe: My vote of 5memberLukasz Swiatkowski16 Sep '12 - 22:54 
Thanks Smile | :)
My website: www.lukesw.net

QuestionTwo ToolStripDropDown at the same timememberIvan Chepiga2 Nov '11 - 22:19 
How can I show two popoup at the same time?
Many thanks in advance
QuestionShow(ToolStripItem) overload [modified]memberMember 38586382 Nov '11 - 6:11 
Thanks for the easy popup control. I wanted to show it under toolstrip buttons, so I added the following overload:
/// <summary>
/// Shows the pop-up window below the specified ToolStripItem.
/// </summary>
/// <param name="toolStripItem">The ToolStripItem below which the pop-up will be shown.</param>
/// <remarks>
/// When there is no space below specified ToolStripItem, the pop-up control is shown above it.
/// </remarks>
/// <exception cref="T:System.ArgumentNullException"><paramref name="toolStripItem"/> or its Owner property is <code>null</code>.</exception>
public void Show (ToolStripItem toolStripItem)
{
    if (toolStripItem == null || toolStripItem.Owner == null)
        throw new ArgumentNullException("toolStripItem");
 
    resizableTop = resizableLeft = false;
    Rectangle area = toolStripItem.Owner.RectangleToScreen(toolStripItem.Bounds);
    Point location = new Point(area.Left, area.Top + area.Height);
    Rectangle screen = Screen.FromRectangle(area).WorkingArea;
    if (location.X + Size.Width > (screen.Left + screen.Width))
    {
         resizableLeft = true;
         location.X = (screen.Left + screen.Width) - Size.Width;
    }
    if (location.Y + Size.Height > (screen.Top + screen.Height))
    {
         resizableTop = true;
         location.Y -= Size.Height + area.Height;
    }
 
    Show(location, ToolStripDropDownDirection.BelowRight);
}


modified 2 Nov '11 - 12:34.

QuestionCheckboxComboBox should allow text search like ComboBoxStyle = DropDown which is not happening :(memberMember 827966029 Sep '11 - 18:18 
Hi
 
I have a CheckBoxComboBox deriving from PopupCombobox.
 
And the requirement as it currently is : Whenever a user click on the drop down, it pop up a combobox styled list containing all checkbox items with scroll down option (Similar to combobox with the comboboxstyle = dropdownlist and not dropdown). So as the user clicks (Checks every checkbox), the item details are filtered as rows (I mean, it filters based on items selected dynamically and displays only those rows).
 
But, now the requirement is, the above functionality should also have the user type any item name in the textbox and the filtering should happen dynamically. So, in order to accomplish this, when I try to change the comboboxstyle to dropdown, the style of combobox in output is changed, but when I type any characters, it doesnt takes at all Frown | :(
 
I want to know why and what I should do to get rid of this. Also, the filtering should be done as and when the user types the items (Similar to when user checks the checkbox of different items in the combobox dropdown).....Remember without clicking the dropdown... Smile | :)
 
Please help me. Its a winform C# app....
QuestionPopping up MonthCalendar ControlmemberMember 226177512 Aug '11 - 5:52 
When the MonthCalendar control is popped up it shows normally but when the year decrement button is pressed the date more than the currently selected date is not shown. THis happens even if we simply drags a MonthCalendar control onto the form and run the app.
QuestionThe thing with the dropdown Arrowmemberpamkkkkk23 Jun '11 - 22:41 
Some Times there is only a small difference, between to make things work and make it work correctly ! Wink | ;)
 
You are using for the drop down Arrow, the Font Marlett and the Char 'u' to display it (if I see it correctly).
But whats shows up, if the User did not have installed the Font!? (Chinise People, or Kyrylic ...)
 
So using Font is not the solution!
 
Next idea can be, to use a Bitmap to show the Arrow.
Yes! That is working!
But what if the user changes his VisualStyles onto Windows ?
It Looks ugly !?
 
But Microsoft has a better solution for us (wich is harder to code)
Look into the sourcecode of this Project into the overridden Paint event Handler:
http://msdn.microsoft.com/en-us/library/aa480727.aspx
 
In case, the User hase switched on the VisualStyles, the ComboBoxRenderer.DrawDropDownButton will be used to display every Button state correctly (ComboBoxState.Pressed or ComboBoxState.Hot ...)
 
If the User doesnot switched on the VisualStyles, you have to draw the Arrow with graphics.DrawPolygon by your self and the background of the Button stays Clean!
 
Just my 50 cent..... Rose | [Rose]
AnswerRe: The thing with the dropdown ArrowmemberLukasz Swiatkowski24 Jun '11 - 2:07 
I understand you, but the sample application is not supposed to be perfect, but only to give general idea how the popup control can be used. In real application I would use the solution you described, but not in the sample application—I wanted it to be as simple as possible.
 
Otherwise, you are right, and one should always use visual style renderers Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralRe: The thing with the dropdown Arrowmemberpamkkkkk24 Jun '11 - 2:40 
Yes il be with you!
The Demo is cleaner without those verbose and complicated code!
This was more, to mention it to the audience!
 
So! Live long and prosper!
And take care of the German - Polish friendship Wink | ;)
GeneralMy vote of 5memberpamkkkkk23 Jun '11 - 21:36 
Very Useful! And well Documented!
GeneralRe: My vote of 5memberLukasz Swiatkowski24 Jun '11 - 2:02 
Thank you Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralThank you!memberRavi Bhavnani23 Apr '11 - 16:12 
Thanks for the ToolStripDropDown/ToolStripControlHost tip, Lukasz!  Got my 5! Thumbs Up | :thumbsup:
 
/ravi
My new year resolution: 2048 x 1536
Home | Articles | My .NET bits | Freeware
ravib(at)ravib(dot)com

GeneralRe: Thank you!memberLukasz Swiatkowski24 Jun '11 - 2:01 
Thanks Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

QuestionDo you have old version for .net 2.0 framework ?memberBerni124 Feb '11 - 11:13 
looks like a great control. Do you have source code for the older version? I'm looking for 2.0 framework ?
AnswerRe: Do you have old version for .net 2.0 framework ?memberLukasz Swiatkowski24 Feb '11 - 20:23 
The current source is still compatible with .NET 2.0 (e.g. there is no System.Core.dll used), so you can compile it by yourself. Or, you can simply download the compiled version (there are 2 dlls—one for .NET 2.0, and one for .NET 4.0).
 
Luke
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralMy vote of 5memberMember 25952581 Jan '11 - 7:53 
Five Stars from me too. Great Stuff.
GeneralRe: My vote of 5memberLukasz Swiatkowski24 Jan '11 - 18:45 
Thank you Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralGreat Control, but how to manage textbox focus..! [modified]membernnihadnoordeenn12 Nov '10 - 2:16 
Hi,
This is an excellent code. I really appreciate you.
Thumbs Up | :thumbsup:

modified on Saturday, November 13, 2010 12:48 AM

GeneralRe: Great Control, but how to manage textbox focus..!memberLukasz Swiatkowski24 Jan '11 - 18:44 
Thank you Smile | :)
My website: www.lukesw.net
My blog: blog.lukesw.net

QuestionRe: Great Control, but how to manage textbox focus..! [modified]memberMember 354174623 Apr '12 - 20:33 
Same problem here. How did you solve this problem. On TextBox key press i open Popup. I use
popup = new Popup(_table);
_popup.FocusOnOpen = false;
The TextBox still has IBeam cursor blinking but not receiving input.
Make love not war

GeneralGreat StuffmemberJonathan C Dickinson21 Oct '10 - 23:03 
You could use a Form and override ActivateOnShow (or something along those lines) to return false; you can then resort to hacks for forward keypresses/etc. to that window from the parent window. That's what I used to do.
 
Yours is by far the most correct solution. Good job on a high quality and well-thought out article. You have my 5.
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
 
Jonathan C Dickinson (C# Software Engineer)

GeneralRe: Great StuffmemberLukasz Swiatkowski22 Oct '10 - 0:16 
Thank you Smile | :)
~~~~~~~~~~~~~~~~
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralPopup Resize sometimes doesn't work on a multi monitor systemmemberdeep4219 Oct '10 - 0:39 
Hi,
 
Resizing of a popup doesnt work, if the popup to resize is on a monitor "left" of the main monitor. Reason is a minor bug in NativeMethods.LOWORD, which is called in OnNcHitTest.
 
Changeing the method to
 
internal static int LOWORD(int n)
{
  unchecked
  {
    return (short)(n & 0xffff);
  }
}
 
solves the problem. The original implementation didnt take care of a possible minus sign.
 
Regards
Peter
 
P.S.
Wonderful tool. Thank you.
GeneralRe: Popup Resize sometimes doesn't work on a multi monitor systemmemberLukasz Swiatkowski20 Oct '10 - 9:16 
Thanks for finding and fixing the bug Smile | :) I’ll include this soon in the next version.
Regards,
Luke
~~~~~~~~~~~~~~~~
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralClosing PopupmemberBenjoD4 Oct '10 - 2:51 
I am trying to implement the popup and I am trying to add a close button from within the usercontrol. How do I close the popup/usercontrol from within the usercontrol itself?
GeneralRe: Closing PopupmemberBenjoD4 Oct '10 - 3:25 
I figured it out ... this.Parent.Close(). Thank you. Smile | :)
GeneralGreat jobmemberSantiago Santos Cortizo9 Sep '10 - 1:30 
Very useful tool. It's just what I was looking for. But I think I've found a little problem: Hide() method seems not working when AutoClose property is False.
 
Thanks.
GeneralRe: Great jobmemberLukasz Swiatkowski20 Oct '10 - 9:15 
Use the Close() method instead of Hide().
~~~~~~~~~~~~~~~~
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralVery nice controlmemberMike Hankey12 Aug '10 - 15:11 
Lukasz,
 
Nice control and easy to use.
 
Thanks for the effort
The happiest people don't have the best of everything, they just make the best of everything they have.
http://www.hq4thmarinescomm.com[^]
My Site
 

GeneralRe: Very nice controlmemberLukasz Swiatkowski20 Oct '10 - 9:10 
Thanks and you’re welcome Smile | :)
~~~~~~~~~~~~~~~~
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralFix for focus problem with PopupComboBox.memberwout de zeeuw25 May '10 - 1:49 
Hi,
 
Wonderful article! One small problem: in application MoreComplexPopup, the dropdown for the PopupComboBox on the top right doesn't get focus (on Windows 7), so you need to click once for it to receive focus, and then click another time to click on an item.
 
Fix: in class PopupComboBox, method WndProc, do BeginInvoke(new MethodInvoker(ShowDropDown)); instead of ShowDropDown() directly.
 
Not sure why the original PopupComboBox won't focus properly though, it has something to do with the ComboBox/WndProc combination perhaps, because all the other drop down examples seem to Focus fine.
Wout

GeneralRe: Fix for focus problem with PopupComboBox.memberLukasz Swiatkowski20 Oct '10 - 9:10 
Thanks for finding and fixing the bug Smile | :) I’ll include this soon in the next version.
~~~~~~~~~~~~~~~~
My website: www.lukesw.net
My blog: blog.lukesw.net

GeneralGracias por este controls.memberReyes-Solutions27 Mar '10 - 17:02 
Saludos, maravilloso controls, despues de horas de trabajo, con su controls resolvi mi problema en 5 minutos. Blush | :O
Questionuse as intellisense?memberMSeirer8 Mar '10 - 12:34 
heya lukasz,
 
thx for this nice control! Smile | :)
 
i am thinking about using this as a basis for a intellisense-like control
i want to type in a TextBox and on the TextChanged event i want to show the
popup and let it filter its ListBox.
 
i expected the property "FocusOnOpen" to help me achieve this. but the focus
after the popup is shown is not in the owner-form. a
 
((TextBox)sender).Focus();
 
doesnt help.
 
do you have an idea how to solve this?
 
best regards
AnswerRe: use as intellisense?memberaaroncampf24 Jan '11 - 12:10 
ComboBoxes have something like this when you set the autocomplete to suggest
GeneralRightToLeft forms problemmemberAbdelRahman Doghish2 Feb '10 - 0:01 
Dear,
 
When I try to add a form that is has the property (RightToLeft = RightToLeft.Yes); the popup throws the following exception (Error creating window handle.).
Note that the problem is solved when I changed the value of this property only and make it (RightToLeft = RightToLeft.No)
 
Code:
 
frmDetail.RightToLeft = RightToLeft.Yes;
Popup popupScreen;
popupScreen = new Popup(frmDetail);
 
//The last line throws the exception
 
Is there any solution for this problem because I want to add a RightToLeft form to the popup?
Thank you very much in advance for your cooperation.
 
Best Regards,
AbdelRahman Doghish

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 27 Mar 2013
Article Copyright 2007 by Lukasz Swiatkowski
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid