Most C++ programmers know how to start coding from an empty project without the wizard’s assistance. But how many tutorials show a way to do this in C#? Questions arise like what references you need, what should the default project settings be, etc.
In this post I’m going to create a Windows Form application starting from scratch (just an empty project). It’s actually quite easy if you’re making a DLL, Console application, or Forms application. Plus, you can be certain that your application doesn’t contain any useless references or dependencies.
Note: this tutorial is applicable to Visual Studio 2008.
Step 1 – Create an Empty Project
Start Visual Studio and select “File->New Project.” When the “New Project” dialog appears, select the “Empty Project” template and name it whatever you like. Click OK.
Step 2 – Modify Project Settings
At this point you’ll have an empty project loaded in Solution Explorer without any source files or references listed. Now, go to the “Project” menu and select “Properties.” Under the “Application” tab, click the “Output type” combo box and change it from “Console Application” to “Windows Application.” This makes the project into a regular Windows Form app.
Save this configuration (hit CTRL-S or click “File->Save”) and close the “Project Settings” window.
Step 3 – Add References
Now right click on the “References” folder in Solution Explorer and click “Add Reference” (you can also select the same option from the “Project” menu). Which references you’ll need will depend on what kind of project you’re building, but in our case we need “System,” “System.Windows.Forms,” and “System.Drawing.” They are located in the .NET tab of the “Add Reference” dialog:
After you’ve selected all three references, click OK. Now your project should look like this in Solution Explorer:
FYI: for almost any project you’ll at least need the “System” reference, so I add this one right away no matter what kind of project I’m creating. If your project was extremely simple, had no dependencies, and you didn’t care about fully qualifying your types, then you could get away with not adding this reference.
Step 4 – Add a Source File
You’ll notice from the last screenshot that we don’t have any source files in our project. Well that’s easy to fix – click on “Add New Item” located under the “Project” menu. When the “Add New Item” dialog appears, select “Code File.” Name it whatever you like and click OK.
Step 5 – Add Code
We didn’t want to select the “Class” template because that would cause Visual Studio to create a class skeleton and add useless references to the project. Selecting “Code File” ensures that nothing is done which isn’t completely necessary. It also gives us an entirely blank source file. Here is the minimum amount of code you’ll have to add for some meaningful output:
- Type the “using” directives for “System,” “System.Windows.Forms,” and “System.Drawing.”
- Type a namespace declaration.
- In that namespace type a class declaration deriving from “Form”.
- Type a “static void Main()” function into the class.
- Inside the Main() function type this line: “Application.Run(new MyClass());”
After following the steps above, your code should look similar to this:
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MyProject
{
class MyClass:Form
{
static void Main()
{
Application.Run(new MyClass());
}
}
}
You can actually compile and run the project in this state, but it will just produce a blank form and you won’t be able to add controls in the Designer. We’ll take care of this problem in the next step.
Step 6 – Add Controls to Form
You may be wondering how to associate your hand-written code with Visual Studio’s Designer. Believe it or not, there’s no need to do this. In fact, Visual Studio automatically detects whenever you derive a class from “System.Windows.Forms.Form” and links the associated source file to the Designer.
Now, right click on your source file in Solution Explorer and select “View Designer.” When the Designer comes up you’ll see an empty form. Drag a button control on it and switch back to code-view. You’ll notice that Visual Studio has added this function to your class:
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(104, 93);
this.button1.Name = “button1”;
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = “button1”;
this.button1.UseVisualStyleBackColor = true;
//
// MyClass
//
this.ClientSize = new System.Drawing.Size(284, 264);
this.Controls.Add(this.button1);
this.Name = “MyClass”;
this.ResumeLayout(false);
}
Visual Studio automatically keeps InitializeComponent() up-to-date. It contains all the code for creating and positioning the form’s controls. However, we still have to call the function. For this, we turn to the class’s constructor. Since we haven’t defined a constructor yet, we’ll do it now and add the call to InitializeComponent():
MyClass()
{
InitializeComponent();
}
By now, your source code should look like this:
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MyProject
{
class MyClass:Form
{
private Button button1;
MyClass()
{
InitializeComponent();
}
static void Main()
{
Application.Run(new MyClass());
}
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(104, 93);
this.button1.Name = “button1”;
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = “button1”;
this.button1.UseVisualStyleBackColor = true;
//
// MyClass
//
this.ClientSize = new System.Drawing.Size(284, 264);
this.Controls.Add(this.button1);
this.Name = “MyClass”;
this.ResumeLayout(false);
}
}
}
Step 7 – Compiled and Run
Now try running the project! Hopefully you see something similar to my output:
Congratulations! You just created a Windows Forms application from scratch!
Optional Things
You may be thinking, “but what about the extra code the wizard adds in forms like Dispose() and the “components” member? Don’t I need that stuff too?” The short answer: it depends.
In certain situations you’ll need the “components” member, but it’s not necessary to define it. The Designer will add the declaration when it’s needed. Try placing a Notify Icon or Timer control and you’ll see what I mean. The “components” member is used for most of the non-visual controls available in the Designer. If you drag a control on a form and it gets added to the container bar (on the bottom of the design window) instead of making some visual appearance on the form itself, then there’s a good chance it’ll use this variable.
You’ll need the Dispose() function only if you must explicitly free resources that can’t otherwise be managed by the Garbage Collector. These resources might be unmanaged memory, file handles, database connections, or similar objects who’s destruction is non-deterministic. Given that our example program allocated objects only from the managed heap, having a Dispose() would be pointless.
If you find that your class will eventually need the “components” member and a Dispose() method, here’s the minimum amount of code you’ll need to get started:
// Special Designer variable
private System.ComponentModel.IContainer components = null;
// Used to explicitly free any resources not
// managed by the Garbage Collector
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Also, you may have noticed that when using the wizard to generate a project, it creates a separate form class instead of using the application’s main class as the container. This results in two extra source files being added to the solution. You can do this yourself by creating one source file giving it a “.cs” extension (such as “Form.cs”) and creating another file with the same name but giving it a “.Designer.cs” extension (such as “Form.Designer.cs”). Visual Studio will automatically associate these two files together and you’ll see “Form.Designer.cs” underneath “Form.cs” in Solution Explorer’s tree view:
Conclusion
I hope that this post has given you insight into rolling your own Windows Forms project from scratch. While it will always be faster to use the wizard, at least now you don’t have to rely on it. You also know what parts of the wizard’s code can be deleted if your program doesn’t require it.
-Greg Dolley
*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.