Four Function Calculator using C# and Windows Forms

by Kam-Hung Soh (kamhung dot soh at gmail dot com) 2009/05/24 03:59:45

Index Copyright About Blog

Introduction

Calculator

This article describes implementing a four-function calculator application in C# and Windows Forms, using Visual Studio C# 2008 Express (VSCE2008), based on source code from an earlier Java version. As before, a four-function calculator is a common exercise to write a application slightly more complex than Hello World. My goal for writing this version is to learn how to drive VSCE2008.

Unlike the earlier Java article, this article skips the analysis of the exercise and focuses on VSCE2008 development features.

Architecture and Implementation

Folder Structure

VSCE2008 organizes the project source in the following manner:

./InfixCalculator:
InfixCalculator.csproj
InfixCalculator.csproj.user
InfixCalculator_TemporaryKey.pfx
InfixCalculatorForm.cs
InfixCalculatorForm.Designer.cs
InfixCalculatorForm.resx
Model.cs
Program.cs
Properties/
Resources/

./InfixCalculator/Properties:
AssemblyInfo.cs
Resources.Designer.cs
Resources.resx
Settings.Designer.cs
Settings.settings

./InfixCalculator/Resources:
InfixCalculator_32x32.ico
InfixCalculator_32x32.xcf

The PFX (Personal Information Exchange) file is a key used for signing the .Net assemblies, if these assemblies are used by other applications. Not sure how it differs from SNK (Strong Name Key) files.

If you use the IDE to design the user interface of your form, a corresponding Designer.cs file is created. This file contains a series of C# statements to add Windows controls into your form.

The IDE also creates a resx file for each form. In this application, the resx file contains the definition of the application icon (image in the top left hand corner of the title bar) and menu strip's position information. It's not clear to me why the menu strip's position is stored separately from the Designer.cs file.

The IDE creates a Properties folder for the properties of the application's namespace. Resource keys defined in Properties/Resources.resx are visible in the IDE's text completion in <Namespace>.Properties.Resources.<ResourceName> . The Properties/Settings.* files are used for storing user preferences, but I didn't test it out in this application. In both cases, the IDE maintains an intermediate C# mapping file Properties/*.Designer.cs for the text completion feature.

Model-View-Controller

I copied the model-view-controller (MVC) implementation from the original Java source code, making some slight modification to suit VSCE2008. As in the original, the controller processes the user's input (the doClick() method). The text display (view) is updated in doEdit() when the user enters a number, while the model is updated in doEvaluate() when the user enters an operator (see code below from InfixCalculatorForm.cs). The doClick method is a called by a button's Click method.

    52      private void doClick(object sender, EventArgs e) {
    53        Button b = sender as Button;
    54        String input = b.Text;
    55        String buffer = this.textBoxNumber.Text;
    56
    57        if (Regex.IsMatch(input, RE_EDIT)) {
    58          buffer = doEdit(buffer, input);
    59        } else if (Regex.IsMatch(input, RE_EVALUATE)) {
    60          buffer = doEvaluate(buffer, input);
    61        }
    62        previousInput = input;
    63        this.textBoxNumber.Text = buffer;
    64      }

Menu Items

The menus and menu items are defined using instances of MenuStrip and ToolMenuStripItem classes, respectively. For instance, below is the definition of the File menu created by the IDE in InfixCalculatorForm.Designer.cs.

    71        this.fileToolStripMenuItem.AutoToolTip = true;
    72        this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
    73              this.exitToolStripMenuItem});
    74        this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
    75        this.fileToolStripMenuItem.ShortcutKeyDisplayString = "";
    76        this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
    77        this.fileToolStripMenuItem.Text = "File";
    78        this.fileToolStripMenuItem.ToolTipText = "File";

Here's how the fileToolStripMenuItem is added to the menu bar in InfixCalculatorForm.Designer.java:

    60        this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
    61              this.fileToolStripMenuItem,
    62              this.helpToolStripMenuItem});

Layout

The layout of the single-line text display and buttons are controlled by a TableLayoutPanel. Unlike the Java version where the button were created and placed programmatically, I used the IDE to define and place all the buttons in the form. Placing 25 very similar buttons in a form using an IDE or entering values in a text editor is fairly tedious but at least I only have to do it once. The IDE generates creates the buttons, places them in the table and sets their properties in separate sections of InfixCalculatorForm.Designer.java.

    33        this.button1 = new System.Windows.Forms.Button();
   …
   118        this.tableLayoutPanel1.Controls.Add(this.button1, 0, 3);
   …
   152        this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
   153                    | System.Windows.Forms.AnchorStyles.Left)
   154                    | System.Windows.Forms.AnchorStyles.Right)));
   155        this.button1.Location = new System.Drawing.Point(3, 81);
   156        this.button1.Name = "button1";
   157        this.button1.Size = new System.Drawing.Size(39, 20);
   158        this.button1.TabIndex = 0;
   159        this.button1.TabStop = false;
   160        this.button1.Text = "1";
   161        this.button1.UseVisualStyleBackColor = true;
   162        this.button1.Click += new System.EventHandler(this.doClick);

Some button properties, such as Location or Size, are no longer required because the TableLayoutPanel does the layout, but the IDE does not remove the unused properties.

Resources and Customization

There's no support for customization in this version of the calculator.

Converting Java to .Net

Converting string-related Java methods to .Net methods is straightforward because they tend to have the same names with different initial letter cases. For instance, Java String.contains() can be replaced by .Net's String.Contains(). It would be worthwhile producing a simple mapping chart between Java and .Net methods to make it easier to swap between the two environments.

Concluding Remarks

A simple four-function calculator was implemented in C# and Windows Forms. We discussed how Visual Studio C# 2008 Express structures source code and generates code for the user interface. In the course of converting the code, I also corrected some minor mistakes in the original Java code.

Some topics for further work:

References

Index Copyright About Blog