This tutorial covers:
In this lab we will continue to learn more about C# by doing some basic GUI programming. We will create a program that plots a few simple 1D functions. Here are the first steps you need to follow:
The picture in the center is the plot of a constant function (f(x)=k). We can plot a linear function (f(x)=x) by selecting "Linear" in the "Function: " combo box. We can left-click-and-drag on the plot to pan the plot.
The next section describes the code layout. You can skip this section if you are already familiar with C# constructs and have no problem understanding the code base.
The code is separated into two files: Function1D.cs and MainForm.cs. Function1D.cs contains respresentation for 1D functions while MainForm.cs contains the code to create GUI elements and handle user interactions.
evalIntern
and ToString
functions. The two provided functions are fairly self explanatory in their structure.
A point of interest is lines like:
public double m { get; set; }
.
get
and set
are keywords in C# used as implicit property accessor functions. This code is equalivalent to
public double m;
public double getm() { return m; }
public void setm(v) { m=v; }
This is simply a short hand for property functions in languages like Java. Using get
and set
abstracts out the internal representation of m
. While this feature is not of great importance in this context, you might find it a useful tool in future projects. You will see similar application in the other source file. You can find more information about get/set
here.
MainForm.cs contains the creation and interaction of the GUI elements. Most of the code should be easy to understand, but we will go over some of the more important details here.
The PlotForm
class represents the graph element in the middle of the program. PlotForm extends from the class PictureBox, which is a C# GUI object is used for arbitrary 2D picture. The plot
function draws the our function by breaking it up into small pieces of lines. The drawTicks
function draws the x and y axes along with ticks on the axes. Both of these functions use the screenToPlot
and/or the plotToScreen
function to transform screen coordinates to plot coordinate or vice-versa.
MainForm
class is the main window element that contains all the GUI components. It contains the Main
function, which is the entry point of the program. Furthermore, MainForm has two corresponding member objects: _plotform
and _funcCombo
. They correspond to the two GUI elements in the window: one is the plot picture, and the other is the combo box for selecting the different plot functions.
We see in MainForm.cs the following function declaration:
private void screenToPlot(float sx, float sy, out float x, out float y)
The out
keyword here is a special feature of C#, not available in Java or C/C++. It is essentially a pass-by-reference declaration for the variables x
and y
. This allows us to return more than a single value (e.g. two values for x and y) per function. It is different from the call-by-reference in C/C++ in that screenToPlot must assign values to x
and y
before the function exits. Otherwise, it is an compilation error. Much like how if a function is declared to return an integer, then not returning an integer before the function ends will cause a compilation error. You can learn more about different ways of parameter passing in C# here.
A delegate in C# is a pointer to a function. Essentially, it allows us to treat functions as variables and pass them as arguments to other functionsand/or use them as we would regular variables. C# handles user interaction in two primary ways.
First, if we are subclassing a C# windowing object (such as PlotForm subclassing PictureBox), then we can override reactive functions (OnMouseMove
) that are called when an event occurs (mouse moving on the picture).
Second, if we decide to use an C# supplied GUI object without modification (such as ComboBox _funcCombo
), then we can provide the object with a delegate (funcSelectionChanged
) that will be called when an event occurs (function selection changes from Constant to Linear). The way we provide such a delegate is through this line:
_funcCombo.SelectedIndexChanged+=new EventHandler(funcSelectionChanged);
SelectedIndexChanged
is just one of many events associated with the ComboBox object. More information about delegates can be found here.
x
), and draw the text
(x,f(x))
for the point (x,f(x)) on the plot. This feature should be enabled/disabled through a checkbox.