03
12/10
Weaning Yourself Off of Visual Studio (Part 2)
So, now that you can compile your *.cs files—made without Visual Studio—into *.exes and *.dlls, what’s the next step to emancipating yourself from Visual Studio? Most of the coding that you do in Visual Studio for—for example—a console application is writing actual code. It’s the Windows Forms Applications that really involve a VS-specific tool—i.e. the designer—so that’s what I’m going to tackle next.
All the knowledge that I have about this was gained through study of the library pages on MSDN and through study of the Visual Studio-generated *.designer.cs files that it generates as you use the designer.
One positive thing that I have found about not using the designer, and actually writing your own code to setup your Windows Forms, is the fact that you wind up with much better-designed Windows Forms on average, since you’re not just wantonly dragging-and-dropping controls (which is woefully imprecise) but are rather setting the controls to locations and sizes which are exact pixels, allowing you to easily normalize inter-control spacing et cetera.
The first thing to understand is that a Windows Form is just a class, and that when you design a new Windows Form (i.e. a custom one for your application), you’re just subclassing from this, piggybacking on its existing functionality, and tacking your own on.
Without Visual Studio there to do it for you, unless you feel like doing unnecessary typing, you’re going to need to use the namespace that Windows Forms classes are in—System.Windows.Forms. Once you’ve done this, you can create your class by declaring it and declaring that it inherits from Form.
Because you don’t have Visual Studio around to setup the form for you when it’s instantiated using code created from the designer, you’re going to need to define a constructor for this class—it’s in here that you’ll create and setup all the controls you want to put on the form, as well as other variables etc. that your application needs to run.
Lastly—as you hopefully know—C# programs don’t just startup and magically construct a class, they need an entrypoint (public static void Main () { }) which tells it what to do. You can easily create a new class to contain this method, or put it in the form’s class. I prefer the former, but it doesn’t matter. In this method, all you’re going to do is call Application.Run() on a new instance of the class of form you created.
Here’s what your completed Windows Form Application skeleton is going to look like:
using System; using System.Windows.Forms; public static class NewApplication { public static void Main () { Application.Run(new NewForm()); } } public class NewForm : Form { public NewForm () { } }
If you compile and run this, it should give you—when run—a blank form which persists until you close it or kill the process.
Now that we can create the skeleton of a Windows Form Application that VS abstracts away, let’s focus on putting some functionality into it. The System.Drawing namespace is going to be important for this endeavour, because it contains two important structures—Point (used to position controls) and Size (used to define the size of controls)—so you’re going to want to add a “using” directive for it at the top of the file.
When you create a control, there’s 4 basic things that you’re probably going to want to do:
- Construct it (e.g. “Button button=new Button();“).
- Size it by assigning a Size to its Size property (e.g. “button.Size=new Size(100,20);“)—bear in mind that both Size and Point use usual cartesion co-ordinate ordering—i.e. x,y.
- Position it by assigning a Point to its Location property (e.g. “button.Location=new Point(10,10);“)—remember that these points are the position of the control’s upper-left corner.
- Add the control to the form’s Controls property, which is a list of the controls which are on the form. If you forget this step the control will not appear. E.g. “Controls.Add(button);“—since you’re working within the class, you don’t need to specify its name, although you can use “this” if you’re feeling verbose.
This is just the very basic setup required to get a control up-and-running. Different controls will have different properties you’ll want to set when you construct them, and this is what the MSDN Library is great for.
The last thing that you need to know how to do to get totally away from Visual Studio when creating Windows Forms Applications is how to handle events. In Visual Studio you can just double-click something, and Visual Studio will create all the required code to setup the event behind-the-scenes. Unlike Visual BASIC (atrocious language…) C# doesn’t have “Handles” syntax for events, even though “event” is a first-class citizen of the C# language. Instead you setup your events in a more reasonable manner—by subscribing to them.
The Visual BASIC method of setting up event handlers defies a well-established paradigm in computer science—i.e. you declare where a pointer goes to, not where it comes from. The Visual BASIC “Handles” syntax obviously stands in defiance of this, and is an example of why—in my opinion—Visual BASIC is a terrible language.
Anyway, classes define events—you can find them on their MSDN Library page—and to handle them you have to subscribe to them by giving the class a delegate that you want to be invoked when the event occurs. Since C# is typesafe, and delegates are just typesafe function pointers, it matters what the signature is of a function that you pass to an event handler—you can’t just pass any old function. The signature of the delegates that can be passed to each event are documented in the MSDN Library. For example, if I wanted to handle the KeyPress event of a Form, I would need to subscribe a function that matches the signature defined by the KeyPressEventHandler delegate. To subscribe to an event, the “+=” syntax is used, and to unsubscribe the “-=” syntax is used.
Here’s a sample application that creates a Form with a Button, which when clicked, creates a MessageBox:
using System; using System.Windows.Forms; using System.Drawing; public static class NewApplication { public static void Main () { Application.Run(new NewForm()); } } public class NewForm : Form { public NewForm () { ClientSize=new Size(120,45); Text="Test Windows Form Application"; Button button=new Button(); button.Text="Click me!"; button.Size=new Size(100,25); button.Location=new Point(10,10); button.Click+=Button_Click; Controls.Add(button); } private void Button_Click (Object sender, EventArgs e) { MessageBox.Show( "You clicked the button!", "Alert!", MessageBoxButtons.OK, MessageBoxIcon.None ); } }
And here it is in action:

Next time I’ll be talking about moving your ASP.NET development out of Visual Studio…


