Legacy Guidance:This article preserves historical web development content. For modern .NET 8+ best practices, visit our Tutorials section.
Desktop applications are usually built to use the processing power of desktop computers and provide rich user interfaces compared to browser-based applications. In the early days of Windows, creating desktop applications was tedious because it was based on programming directly with Windows API.
With current .NET technology, building desktop applications is simplified greatly due to facilities like graphical design programming environments with an Integrated Development Environment, code generation for user interface layouts specified as controls in a form, rich sets of base classes with logic for controls, clear language for coding application logic, ability to include customized controls, and compatibility with software designed in earlier Windows versions.
C# and VB.NET for Desktop Development
C# and VB.NET are two languages used to build desktop applications in .NET. Since both offer the same programming environment with the same set of user interface classes and resource editor, there's no major difference in developing a desktop application in C# or VB.NET.
Understanding Windows Forms
The entire programming for desktop applications in .NET is based on Windows Forms or WinForms. It's basically an object-oriented programming model where you can create a desktop application using classes included in the System.Windows.Forms namespace. Using the code generation facility and resource editor provided by Visual Studio IDE, Windows Forms applications can be built faster and easier.
The Form class in the System.Windows.Forms namespace is used as the base class that needs to be derived to create the form where the entire application logic resides. The entry and exit point, implemented in the Main method, for the Windows Forms application is also within this class, centralized in the same place.
Basic Windows Form
using System;
using System.Windows.Forms;
namespace MyDesktopApp
{
public class MainForm : Form
{
public MainForm()
{
// Initialize form
this.Text = "My Application";
this.Width = 800;
this.Height = 600;
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
}
}
Events sent to the application are processed in the Application.Run method in the Main method of the Form class. This takes care of polling the events passed in the message queue and processes them accordingly.
System.Drawing Namespace
System.Drawing is also an important namespace that provides access to basic GDI+ features. This includes all the classes necessary for enhancing functionalities for user controls like modifying standard controls for different appearance and behavior or designing completely new custom controls with user-defined features.
Working with Forms
Every window displayed in a desktop application is considered a form, which can be any type like typical window, main window of Single Document Interface, Multiple Document Interface, dialog box, or message box. A Form is a class that provides properties to set its appearance like size, border style, background color, and controls that can be placed on it.
Form Properties
public MainForm()
{
// Set form properties
this.Text = "Employee Management";
this.Size = new Size(800, 600);
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.BackColor = Color.WhiteSmoke;
this.StartPosition = FormStartPosition.CenterScreen;
this.MaximizeBox = false;
}
Controls in Windows Forms
The System.Windows.Forms namespace provides a wide range of controls representing common Windows user interface elements. Controls like Button, Label, TextBox, ComboBox, ListBox, and many others are available as classes. Each control inherits from the Control base class and can be added to forms.
Adding Controls
public MainForm()
{
// Create label
Label nameLabel = new Label
{
Text = "Name:",
Location = new Point(20, 20),
Size = new Size(100, 20)
};
// Create textbox
TextBox nameTextBox = new TextBox
{
Location = new Point(130, 20),
Size = new Size(200, 20)
};
// Create button
Button saveButton = new Button
{
Text = "Save",
Location = new Point(130, 60),
Size = new Size(100, 30)
};
saveButton.Click += SaveButton_Click;
// Add controls to form
this.Controls.Add(nameLabel);
this.Controls.Add(nameTextBox);
this.Controls.Add(saveButton);
}
private void SaveButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Data saved successfully!");
}
Event-Driven Programming
Windows Forms follows an event-driven programming model. When users interact with controls, events are raised. You handle these events by creating event handlers. The event-driven model uses delegates to specify which method should be called when an event occurs. The two parameters that a delegate takes are the event source as Object type and the event information as EventArgs class.
Three classes are used for building menus. System.Windows.Forms.MainMenu provides the menu structure for a form. System.Windows.Forms.MenuItem represents individual menu items displayed in MainMenu or ContextMenu. System.Windows.Forms.ContextMenu provides shortcut menus displayed during right click of mouse button over a control or area of the form.
Menu Creation
public MainForm()
{
// Create main menu
MenuStrip menuStrip = new MenuStrip();
// File menu
ToolStripMenuItem fileMenu = new ToolStripMenuItem("File");
ToolStripMenuItem newItem = new ToolStripMenuItem("New");
ToolStripMenuItem openItem = new ToolStripMenuItem("Open");
ToolStripMenuItem exitItem = new ToolStripMenuItem("Exit");
exitItem.Click += (s, e) => this.Close();
fileMenu.DropDownItems.Add(newItem);
fileMenu.DropDownItems.Add(openItem);
fileMenu.DropDownItems.Add(new ToolStripSeparator());
fileMenu.DropDownItems.Add(exitItem);
// Add to menu strip
menuStrip.Items.Add(fileMenu);
// Add menu to form
this.MainMenuStrip = menuStrip;
this.Controls.Add(menuStrip);
}
The Visual Studio IDE helps design menus in a faster and simpler way. Code for the logic that needs to be implemented on click of menu item has to be edited in the event handler of the menu item.
Graphics Classes
.NET framework provides classes related to graphics functionality. These classes help programmatically create graphics with numerous options and are included in the System.Drawing namespace. Important classes include:
Graphics Example
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
// Draw line
Pen pen = new Pen(Color.Blue, 2);
g.DrawLine(pen, 10, 10, 200, 10);
// Draw rectangle
g.DrawRectangle(Pens.Red, 10, 30, 100, 50);
// Fill rectangle
SolidBrush brush = new SolidBrush(Color.LightGreen);
g.FillRectangle(brush, 120, 30, 100, 50);
// Draw text
Font font = new Font("Arial", 12, FontStyle.Bold);
g.DrawString("Hello WinForms!", font, Brushes.Black, 10, 100);
// Dispose resources
pen.Dispose();
brush.Dispose();
font.Dispose();
}
Dimension classes like Point, Size, and Rectangle are used for specifying dimensions. Different types of Brush classes are available to fill the interior of graphical shapes. Pen objects draw lines and curves with selected color and thickness. Font is used for formatting text. The Graphics class provides methods for drawing and can save output in various formats like JPG, BMP, etc.
Custom Controls
Sometimes you need to design a user interface control different from standard controls provided by the framework to cater to a specific data model and user interaction. The framework offers the facility to design customized controls derived from System.Windows.Forms.UserControl. Define required properties for look and behavior, and override the OnPaint method to specify customized rendering logic.
Custom Control
public class CustomButton : UserControl
{
private Color buttonColor = Color.Blue;
private string buttonText = "Click Me";
public Color ButtonColor
{
get { return buttonColor; }
set { buttonColor = value; this.Invalidate(); }
}
public string ButtonText
{
get { return buttonText; }
set { buttonText = value; this.Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
// Draw custom button
SolidBrush brush = new SolidBrush(buttonColor);
g.FillRoundedRectangle(brush, 0, 0, this.Width, this.Height, 10);
// Draw text
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString(buttonText, this.Font, Brushes.White,
this.ClientRectangle, format);
brush.Dispose();
}
}
Tips for Building Desktop Applications
The main purpose of building the desktop application along with its design objectives like performance, scalability, and security needs to be identified before starting to build the application.
Most desktop applications are resource intensive and need to share resources like CPU memory, disk input and output, and network input and output. By sharing resources properly, performance of all executing applications and the entire system improves.
Application response to users needs greater priority since user interactions are more frequent in desktop applications compared to distributed applications. For this, time-consuming tasks can be executed asynchronously as background tasks, requiring the application to be multithreaded and carefully developed.
Quick FAQ
What's the difference between C# and VB.NET for desktop applications?
Both languages offer the same programming environment with identical UI classes and resource editor. There's no major difference in developing desktop applications between C# and VB.NET. Choose based on your language preference and team expertise.
How do events work in Windows Forms applications?
Windows Forms uses the event-driven programming model. Each control raises events like Click or TextChanged. You subscribe to these events using delegates, and your event handler executes when the event occurs. The Application.Run method processes the message queue.
When should I create custom controls?
Create custom controls when standard controls don't meet your needs for appearance, behavior, or data handling. Derive from UserControl, define required properties, and override OnPaint for custom rendering. This is useful for specialized UI components.