Valentines Message

using System;
using System.Drawing;

namespace Love

    class Flower
        private Color color;
        public Color Color
            get { return this.color; }
            set { this.color = value; }

    class Rose : Flower
        public Rose(Color color)
            this.Color = color;

    class Violet : Flower
        public Violet(Color color)
            this.Color = color;

    interface ICharactaristic
        bool IsSweet { get; set;}

    class Sugar : ICharactaristic
        bool isSweet;

        #region ICharactaristic Members
        public bool IsSweet
            get { return this.isSweet; }
            set { this.isSweet = value; }


    class You : ICharactaristic
        bool isSweet;

        #region ICharactaristic Members
        public bool IsSweet
            get { return this.isSweet; }
            set { this.isSweet = value; }

    class Valentine
        static void Main(string[] args)
            Rose[] roses = new Rose[12];
            Violet[] violets = new Violet[12];

            for (int i = 0; i < 12; i++)
                roses[i] = new Rose(Color.Red);
                violets[i] = new Violet(Color.Blue);

            Sugar sugar = new Sugar();
            sugar.IsSweet = true;

            You you = new You();
            you.IsSweet = true;

An introduction to mock objects

Colin Mackay presenting Mock Objects (Grok Talk)Sometimes when you are unit testing you might get to a point where you say “That’s too difficult to unit test so I’m just going to leave it”. This is where mock objects come in. Mock objects are stand-in dummy objects that don’t have any functionality behind them, they just return the values to the application that the real object would have returned.

Unit tests are supposed to test isolated bits of code. A single method on a class, or a single public method that calls some private methods on the class. Nothing more than that. Mock objects ensure that if the code you are testing calls something external to the class being tested you don’t have to worry about what the actaul real class does. This has some useful advantages.

When mocks are used the external class is not used, therefore any bugs in the external class do not affect the code being tested. The tests for that other class should pick up the bugs. If the external class is non-deterministic then mock objects can be used to ensure that the unit test received known values repeatedly. It would be insane to provide random values in to a test because it may fail intermittently. If you have a bug that causes the code to fail then knowing the values that cause the failure is necessary. If these are known a new unit test that exercises the failing code can be written so that it can be seen when it is fixed. If it starts to fail again then it will be seen instantly.

There are many unit frameworks out there, for this demo I’m using Rhino Mocks by Ayende Rahien. Other frameworks include NMock2, Easy Mock and Type Mock. Mock object frameworks are not strictly necessary. It is possible to set up a mock object just by implementing the interface of the object to be mocked, however this can take a bit more work.

As a general rule classes that are outside the class under test (CUT) should be mocked. There are some exceptions like extremely simple classes such as data transfer objects, whose sole purpose is to transfer data without any functionality.

If your class interacts with external systems then the access to those external systems can be abstracted out. Then the interaction with the external system can be mocked. In general this kind of abstraction would normally take place anyway when separating the application into its appropriate modules, assemblies, layers or tiers. For example, if your application relies on some configuration setting, a configuration class would be created that knows what should be in the config file for the application, extracts it and transforms it into values the application can use. If the code being tested needs to access a configuration value, a mock configuration object can be supplied and a strictly defined value will be available for the test. This saves tedious setting up of files in advance of the test run. The same can be achieved with database access, web service access and so on. It is also possible to mock out the user interface if the presenter pattern is used.

At the heart of most mock objects is simply that they provide inputs into the code that is being tested.

The most obvious input into a method is the parameters that are passed in. But the fields of a class are also inputs into the method, and calls to methods and properties are inputs into the method. Mock objects ensure that inputs into a method generated by code outwith the class under test are setup specifically by the unit test.

Let’s take the example of a piece of code that calls into a D.A.L (Data Abstraction/Access Layer). This might be mocked for many reasons.

  • The database may not be available because it is yet to be created or the data hasn’t been migrated yet from an older system.
  • The database may be shared among the developers. In this case the state of the database cannot be guaranteed as other developers may be changing it while tests are running.
  • The database may take too long to set up, or the set up process may have some manual steps. In order for unit tests to be used effectively they need to be easy and quick to run. If they are not then their value quickly diminishes as developers will stop running them so frequently.
  • The unit tests are likely to be run in many different environments and the availability or consistency of the database in those environments cannot be guaranteed. Typically each developer will be running the unit tests on their own machine. In a large team there may be dedicated testers who will be running the unit tests. There may be a system such as CruiseControl that will automatically build and run unit tests whenever it detects a change in the source control database.

Mock object frameworks, such as Rhino Mocks, typically work by setting up a series of commands that it expects to be called, then those commands are replayed into the code that is being tested. Once the code under test is completed then the mock framework verifies that the commands were called. If for example an expectation was that method A is called, but wasn’t the Verify process will throw an exception that the unit test framework will use to report a problem. If, on the other hand, the code calls method B, but that wasn’t expected then the mock object framework will throw a slightly different exception to say that B was not expected to be called.

In the demonstration solution there is a somewhat contrived example of how mocks work. The ProductsFactory class needs to call the Dal in order to work out what products should be instantiated. There are two mock objects at work here. One is the Dal itself and the other is the IDataReader. The unit test code shows the mocks being created and the expectations being set up. It then replays the commands and runs the code that is to be tested. Once the code is run it verifies that the methods have been called. In the second test, where multiple products are returned from the factory, the expectations are set up slightly differently. In this case an additional expecation is being set up that demands that the methods are called in a strict order. In the first unit test the methods could have been called in any order, just so long as they were called.

Further reading/watching


How to get a list of all subdirectories

This is an example of how to obtain a list of all subdirectories using a recursive method with the .NET Framework.

public static List GetSubdirectories(DirectoryInfo directory)
    // Set up the result of the method.
    List<DirectoryInfo> result = new List<DirectoryInfo>();

    // Attempt to get a list of immediate child directories from the directory
    // that was passed in to the method.
    DirectoryInfo[] childDirectories;
        childDirectories = directory.GetDirectories();
    catch (UnauthorizedAccessException uae)
        // If the permissions do not authorise access to the contents of the
        // directory then return an empty list.
        return result;

    // Loop over all the child directories to get their contents.
    foreach (DirectoryInfo childDirectory in childDirectories)
        // Add the child directory to the result list

        // Get any children of the current child directory
        List<DirectoryInfo> grandchildDirectories = GetSubdirectories(childDirectory);

        // Add the child's children (the grandchildren) to the result list.

    // return the full list of all subdirectories of the one passed in.
    return result;

The code requires the following namespaces:

  • System.Collections.Generic
  • System.IO
  • System.Diagnostics

SQL Injection Attacks and Some Tips on How to Prevent Them


Security in software applications is an ever more important topic. In this article, I discuss various aspects of SQL Injection attacks, what to look for in your code, and how to secure it against SQL Injection attacks. Although the technologies used here are SQL Server 2000 and the .NET Framework, the general ideas presented apply to any modern data driven application framework, which makes attacks potentially possible on any type of application that depends on that framework.

What is a SQL Injection Attack?

A SQL Injection attack is a form of attack that comes from user input that has not been checked to see that it is valid. The objective is to fool the database system into running malicious code that will reveal sensitive information or otherwise compromise the server.

There are two main types of attacks. First-order attacks are when the attacker receives the desired result immediately, either by direct response from the application they are interacting with or some other response mechanism, such as email. Second-order attacks are when the attacker injects some data that will reside in the database, but the payload will not be immediately activated. I will discuss each in more detail later in this article.

An example of what an attacker might do

In the following example, assume that a web site is being used to mount an attack on the database. If you think about a typical SQL statement, you might think of something like:

SELECT ProductName, QuantityPerUnit, UnitPrice
FROM Products
WHERE ProductName LIKE 'G%'

The objective of the attacker is to inject their own SQL into the statement that the application will use to query the database. If, for instance, the above query was generated from a search feature on a web site, then they user may have inserted the “G” as their query. If the server side code then inserts the user input directly into the SQL statement, it might look like this:

string sql = "SELECT ProductName, QuantityPerUnit, UnitPrice "+
    "FROM Products " +
    "WHERE ProductName LIKE '""%';
SqlDataAdapter da = new SqlDataAdapter(sql, DbCommand);

This is all fine if the data is valid, but what if the user types something unexpected? What happens if the user types:

' UNION SELECT name, type, id FROM sysobjects;--

Note the initial apostrophe; it closes the opening quote in the original SQL statement. Also, note the two dashes at the end; that starts a comment, which means that anything left in the original SQL statement is ignored.

Now, when the attacker views the page that was meant to list the products the user has searched for, they get a list of all the names of all the objects in the database and the type of object that they are. From this list, the attacker can see that there is a table called Users. If they take note of the id for the Users table, they could then inject the following:

' UNION SELECT name, '', length FROM syscolumns
WHERE id = 1845581613;--

This would give them a list of the column names in the Users table. Now they have enough information to get access to a list of users, passwords, and if they have admin privileges on the web site.

' UNION SELECT UserName, Password, IsAdmin FROM Users;--

Assume that there is a table called Users which has columns called UserName and Password, it is possible to union that with the original query and the results will be interpreted as if the UserName was the name of the product and the Password was the quantity per unit. Finally, because the attacker discovered that there is a IsAdmin column, they are likely to retrieve the information in that too.

Locking down

Security is something that needs to be tackled on many levels because a chain is only as strong as its weakest link. When a user interacts with a piece of software, there are many links in the chain; if the user is malicious, he could attempt to attack these links to find the weak point and attempt to break the system at that point. With this in mind, it is important that the developer does not become complacent about the security of the system because one security measure is put in place, or a set of security measures are in place on only one part of the system.

An intranet website that uses Windows authentication (it takes the user’s existing credentials based on who they are logged in as) and is sitting inside the corporate network and unavailable to Internet users may give the impression that only authorised users can access the intranet web application. However, it is possible for an authenticated user to gain unauthorised access if the security is not taken much beyond that level. Some statistics support the suggestion that most security breaches are insider jobs rather than people attacking the system from outside.

With this in mind, it is important that even if the application permits only valid data through that has been carefully verified and cleaned up, other security measures are put in place. This is especially important between application layers where there may be an increased opportunity for spoofing of requests or results.

For example, if a web application were to request that the user choose a date, then it would be normal that the values for the date are checked in some JavaScript function on the web page before any data was posted back to the server. This improves the user experience by reducing the wait between lots of server requests. However, the value needs to be validated again on the server as it is possible to spoof the request with a deliberately crafted invalid date.

Encrypting data

Starting from the proposition that somehow an attacker has managed to break through all other defenses, what information is so sensitive that it needs to remain a secret? Candidates for encryption include user log in details or financial information such as credit card details.

For items such as passwords, the user’s password can be stored as a “salted hash”. What happens is that when a user creates a password, a randomly generated “salt” value is created by the application and appended to the password, and the password-and-salt are then passed through a one way encryption routine, such as found in the .NET Framework’s helper class FormsAuthentication (HashPasswordForStoringInConfigFile method). The result is a salted hash which is stored in the database along with the clear text salt string.

The value of a salted hash is such that a dictionary attack is not going to work as each dictionary would have to be rebuilt appending the various salt values and recomputing the hash values for each item. While it is still possible to determine the password by brute force, the use of the salt (even though it is known) greatly slows down the process. The second advantage of the salt is that it masks any situations where two independent users happen to use the same password, as the salted hash value for each user would be different if given different salt values.

Least Privilege – Database account

Running an application that connects to the database using the database’s administrator account has the potential for an attacker to perform almost limitless commands with the database. Anything an administrator can do, so can an attacker.

Using the example application above, an attacker could inject the following to discover the contents of the hard disk(s) on the server.

The first command is used to create a temporary store on the database and fill it with some data. The following injected code will create a table with the same structure as the result set of the extended stored procedure that will be called. It then populates the table with the results of the extended stored procedure.

'; CREATE TABLE haxor(name varchar(255), mb_free int);
INSERT INTO haxor  EXEC master..xp_fixeddrives;--

A second injection attack has to take place in order to get the data out again.

' UNION SELECT name, cast((mb_free) as varchar(10)), 1.0 FROM haxor;--

This returns the name of the disks with the available capacity in megabytes. Now that the drive letters of the disks are known, a new injection attack can take place in order to find out what is on those disks.

'; DROP TABLE haxor;CREATE TABLE haxor(line varchar(255) null);
INSERT INTO haxor EXEC master..xp_cmdshell 'dir /s c:';--

And again, a second injection attack is used to get the data out again.

' UNION SELECT line, '', 1.0 FROM haxor;--

xp_cmdshell, by default, is only executable by a user with the sysadmin privilege, such as sa, and CREATE TABLE is only available to sysadmin, db_dbowner or db_dlladmin users. It is therefore important to run the application with the least privileges that are necessary in order to perform the necessary functions of the application.

Least Privilege – Process account

When an instance of SQL Server is installed on a computer, it creates a service that runs in the background and processes the commands from applications that are connected to it. By default, this service is installed to use the Local System account. This is the most powerful account on a Windows machine, it is even more powerful than the Administrator account.

If an attacker has an opportunity to break out of the confines of SQL Server itself, such as through the extended procedure xp_cmdshell, then they could gain unrestricted access to the machine that the SQL Server is on.

Microsoft recommends that during the installation of SQL Server, the service is given a domain account which has the permissions set to only the necessary resources. That way, an attacker is confined by the permission set needed to run SQL Server.

Cleaning and Validating input

In many applications, the developer has side-stepped the potential use of the apostrophe as a way to get access to the system by performing a string replace on the input given by the user. This is useful for valid reasons, such as being able to enter surnames such as “O’Brian” or “D’Arcy”, and so the developer may not even realise that they have partly defeated a SQL injection attack. For example:

string surname = this.surnameTb.Text.Replace("'", "''");
string sql = "Update Users SET Surname='"+surname+"' "+
    "WHERE id="+userID;

All of the previous injection attack examples would cease to work given a scenario like this.

However, many applications need the user to enter numbers and these don’t need to have the apostrophes escaped like a text string. If an application allows the user to review their orders by year, the application may execute some SQL like this:


And in order for the application to execute it, the C# code to build the SQL command might look like this:

string sql = "SELECT * FROM Orders WHERE DATEPART(YEAR, OrderDate) = "+

It becomes easy to inject code into the database again. All the attackers need to do in this instance is start their attack with a number, then they inject the code they want to run. Like this:

0; DELETE FROM Orders WHERE ID = 'competitor';--

It is therefore imperative that the input from the user is checked to determine that it really is a number, and in the valid range. For instance:

string stringValue = orderYearTb.Text;
Regex re = new Regex(@"D");
Match m = re.Match(someTextBox.Text);
if (m.Success)
    // This is NOT a number, do error processing.
    int intValue = int.Parse(stringValue);
    if ((intValue < 1990) || (intValue > DateTime.Now.Year))
        // This is out of range, do error processing.

Second-Order Attacks

A second-order attack is one where the data lies dormant in the database until some future event occurs. It often happens because once data is in the database, it is often thought of as being clean and is not checked again. However, the data is frequently used in queries where it can still cause harm.

Consider an application that permits the users to set up some favourite search criteria. When the user defines the search parameters, the application escapes out all the apostrophes so that a first-order attack cannot occur when the data for the favourite is inserted into the database. However, when the user comes to perform the search, the data is taken from the database and used to form a second query which then performs the actual search. It is this second query which is the victim of the attack.

For example. If the user types the following as the search criteria:

'; DELETE Orders;--

The application takes this input and escapes out apostrophe so that the final SQL statement might look like this:

INSERT Favourites (UserID, FriendlyName, Criteria)
VALUES(123, 'My Attack', ''';DELETE Orders;--')

which is entered into the database without problems. However, when the user selects their favourite search, the data is retrieved to the application, which forms a new SQL command and executes that. For example, the C# code might look like:

// Get the valid user name and friendly name of the favourite
int uid = this.GetUserID();
string friendlyName = this.GetFriendlyName();
// Create the SQL statement to retrieve the search criteria
string sql = string.Format("SELECT Criteria FROM Favourites "+
    "WHERE UserID={0} AND FriendlyName='{1}'",
    uid, friendlyName);
SqlCommand cmd = new SqlCommand(sql, this.Connection);
string criteria = cmd.ExecuteScalar();

// Do the search
sql = string.Format("SELECT * FROM Products WHERE ProductName = '{0}'",
SqlDataAdapter da = new SqlDataAdapter(sql, this.Connection);

The second query to the database, when fully expanded, now looks like this:

SELECT * FROM Products WHERE ProductName = ''; DELETE Orders;--

It will return no results for the expected query, but the company has just lost all of their orders.

Parameterised Queries

SQL Server, like many database systems, supports a concept called parameterised queries. This is where the SQL Command uses a parameter instead of injecting the values directly into the command. The particular second-order attack above would not have been possible if parameterised queries had been used.

Where the application developer would have constructed a SqlCommand object like this:

string cmdText=string.Format("SELECT * FROM Customers "+
    "WHERE Country='{0}'", countryName);
SqlCommand cmd = new SqlCommand(cmdText, conn);

A parameterised query would look like this:

string commandText = "SELECT * FROM Customers "+
    "WHERE Country = @CountryName";
SqlCommand cmd = new SqlCommand(commandText, conn);

The value is replaced by a placeholder, the parameter, and then the parameter’s value is added to the Parameters collection on the command.

While many second-order attacks can be prevented by using parameters, they can only be used in places were a parameter is permitted in the SQL statement. The application may return a variable sized result set based on user preference. The SQL statement would include the TOP keyword in order to limit the result set, however, in SQL Server 2000, TOP can only accept literal values so the application would have to inject that value into the SQL command to obtain that functionality. For example:

string sql = string.Format("SELECT TOP {0} * FROM Products", numResults);

Using Stored Procedures

Stored Procedures add an extra layer of abstraction in to the design of a software system. This means that, so long as the interface on the stored procedure stays the same, the underlying table structure can change with no noticeable consequence to the application that is using the database. This layer of abstraction also helps put up an extra barrier to potential attackers. If access to the data in SQL Server is only ever permitted via stored procedures, then permission does not need to be explicitly set on any of the tables. Therefore, none of the tables should ever need to be exposed directly to outside applications. For an outside application to read or modify the database, it must go through stored procedures. Even though some stored procedures, if used incorrectly, could potentially damage the database, anything that can reduce the attack surface is beneficial.

Stored procedures can be written to validate any input that is sent to them to ensure the integrity of the data beyond the simple constraints otherwise available on the tables. Parameters can be checked for valid ranges. Information can be cross checked with data in other tables.

For example, consider a database that has the user details for a website, this includes the user name and password. It is important that an attacker is unable to get a list of passwords or even one password. The stored procedures are designed so that a password can be passed in, but it will never put a password in any result set. The stored procedures for registering and authenticating a user for the website might be:

  • RegisterUser
  • VerifyCredentials
  • ChangePassword

RegisterUser takes the user name and password as parameters (possibly along with other information that is necessary for registering on the website) and returns the UserID.

VerifyCredentials would be used for logging into the site by accepting the user name and the password. If there is a match the UserID is returned, if not then a NULL value.

ChangePassword would take the UserID, the old password and the new password. If the UserID and the password match, the password can be changed. A value that indicates success or failure is returned.

The above example shows that the password is always contained in the database and is never exposed.

Stored Procedure Caveat

While stored procedures seem to be a wonderful panacea against injection attacks, this is not necessarily the case. As mentioned above, it is important to validate data to check that it is correct and it is a definite benefit of stored procedures that they can do this; however, it is doubly important to validate data if the stored procedure is going to use EXEC(some_string) where some_string is built up from data and string literals to form a new command.

For instance, if the stored procedure is to modify the data model of the database, such as creating a table, the code may be written as follows:

CREATE PROCEDURE dbo.CreateUserTable
@userName sysname
    EXEC('CREATE TABLE '+@userName+
    ' (column1 varchar(100), column2 varchar(100))');

It is obvious that whatever @userName contains will be appended to the CREATE statement. An attacker could inject into the application some code that sets the user name to be:


which will immediately stop the SQL Server without waiting for other requests to complete.

It is important to validate the input to ensure that no illegal characters are present. The application could be set to ensure that spaces are not permitted as part of the user name and this could be rejected before it ever got as far as constructing the CREATE statement.

If the stored procedure is going to construct a SQL command based on an existing object, such as a table or view, then it should check that such an object exists. For instance:

@userName sysname
    AND TABLE_NAME = @userName)
        -- The table is known to exist
        -- construct the appropriate command here

Error Messages

Error messages are useful to an attacker because they give additional information about the database that might not otherwise be available. It is often thought of as being helpful for the application to return an error message to the user if something goes wrong so that if the problem persists they have some useful information to tell the technical support team. Applications will often have some code that looks like this:

     // Attempt some database operation
catch(Exception e)
    errorLabel.Text = string.Concat("Sorry, your request failed. ",
        "If the problem persists please report the following message ",
        "to technical support", Environment.Newline, e.Message);

A better solution that does not compromise security would be to display a generic error message that simply states an error has occurred with a unique ID. The unique ID means nothing to the user, but it will be logged along with the actual error diagnostics on the server which the technical support team has access to. The code above would change to something like this instead:

    // Attempt some database operation
catch(Exception e)
    int id = ErrorLogger.LogException(e);
    errorLabel.Text = string.Format("Sorry, your request Failed. "+
        "If the problem persists please report error code {0} "
         "to the technical support team.", id);


  • Encrypt sensitive data.
  • Access the database using an account with the least privileges necessary.
  • Install the database using an account with the least privileges necessary.
  • Ensure that data is valid.
  • Do a code review to check for the possibility of second-order attacks.
  • Use parameterised queries.
  • Use stored procedures.
  • Re-validate data in stored procedures.
  • Ensure that error messages give nothing away about the internal architecture of the application or the database.

References and related posts

The only authorised versions of this article are available from: The Code Project and my website.

Passing Values Between Forms in .NET


I wrote this article in response to an almost overwhelming number of requests on forums on how to pass a variable from a one Windows Form to another. In fact, saying that it is going between one form and another is somewhat of a misnomer because this will work for any type of object not just Forms. This seems to be one area where beginners in C# and VB.NET often get stuck. So, rather than having to repeat myself often in forums I wrote this article so that I could point people at it so that they will have the benefit of a full explanation as well as the answer to their problem.

The code examples that come with this article are available for VB.NET and C# so that neither group feels left out. If you develop software in any of the other languages available for .NET then you can probably follow on too. The techniques are the same for all .NET languages the only difference should be in the language syntax.

Parent to child

Passing a value from a parent to a child class is hopefully one of the easiest techniques and is the one I’ll start with. The idea is simple. The parent class needs to pass some value to the child class. In this example, I have set up a simple parent form with a TextBox control where the user can type any value they like, then they can open the child form and see that value appear there.

First of all, the child class needs some way to receive the value from the parent. I’ve set up a property to receive the value and it will set the Text value of a TextBox on the child form. In reality this could set a field value or get passed to another object and so on.

public string ValueFromParent
        this.uxParentValue.Text = value;
Public WriteOnly Property ValueFromParent() As String
    Set(ByVal Value As String)
        Me.uxParentValue.Text = Value
    End Set
End Property

Passing the value on construction

To make the initialization of the class easier, the constructor will take a parameter which will be the current value to be passed. The constructor uses the property so that the code can be reused. Admittedly, in this example there is only one line in the property, but as an element of future proofing it means that there is the possibility of adding more functionality to the property in future should it need. That additional functionality will be implemented without having to change a lot of existing code.

public ChildForm(string initialValue)
    ValueFromParent = initialValue;
Public Sub New(ByVal initialValue As String)
    'This call is required by the Windows Form Designer.
    ValueFromParent = initialValue
End Sub

Now, in order for the parent to pass the value to the child, it only has to set the property. For example, when using the child form as a dialog the value from the parent can be passed as follows:

private void uxOpenDialog_Click(object sender, System.EventArgs e)
    // Get the value to be passed
    string parentValue = this.uxUserResponse.Text;
    // Create the child form.
    ChildForm child = new ChildForm(parentValue);
    // Show the form which will display the user's value.
Private Sub uxOpenDialog_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles uxOpenDialog.Click
    ' Get the value that the child will be initialised with
    Dim initialValue As String
    initialValue = Me.uxUserResponse.Text
    Dim childForm As ChildForm
    ' Create the child form.
    childForm = New ChildForm(initialValue)
    ' Show the child dialog.
End Sub

Passing the value while the form is open

Of course, it may be necessary to pass a value when the child form is already open. This is also possible if the parent form stores a reference to the child form and then uses that to pass updates to the child form using the property in the child form that was set up earlier.

In my example, the parent is going to store a reference to the child as a field in the ParentForm class like this:

private ChildForm uxChildForm;
Private uxChildForm As ChildForm

When creating the child form it is therefore important to pass the reference to the child form into the field variable. For example:

private void uxOpenForm_Click(object sender, System.EventArgs e)
    this.uxChildForm = new ChildForm();
    this.uxChildForm.ValueFromParent = this.uxUserResponse.Text;
Private Sub uxOpenForm_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles uxOpenForm.Click
    Me.uxChildForm = New ChildForm
    Me.uxChildForm.ValueFromParent = Me.uxUserResponse.Text
End Sub

Finally, whenever the parent needs to tell the child that the value is updated it can do so just by passing the new value to the property that was set up in the child form. For example:

private void uxUserResponse_TextChanged(object sender, System.EventArgs e)
    if (this.uxChildForm != null)
        this.uxChildForm.ValueFromParent = this.uxUserResponse.Text;
Private Sub uxUserResponse_TextChanged(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles uxUserResponse.TextChanged
    If Not Me.uxChildForm Is Nothing Then
        Me.uxChildForm.ValueFromParent = Me.uxUserResponse.Text
    End If
End Sub

The code for this is in the zip file above. The projects are ParentToChildCS (for C# developers) and ParentToChildVB (for VB developers).

Sibling to Sibling

The next most common request seems to be passing a value between two siblings. That is, two child classes sharing the same parent class. This also demonstrates passing between the child and the parent.

First, it is important to note that in most cases the two child classes should probably know nothing about each other. If the two child classes start to communicate directly with each other the coupling in the application increases and this will make maintenance of the application more difficult. Therefore the first thing to do is to allow the child classes to raise events when they change.

In order to raise events, create a delegate to define the signature of the method that will be called when the event is raised. It is a good practice to conform to the same style as the delegates used in the .NET Framework itself. For example, if an event handler for the Click event of a Button is created then it is possible to see that the signature of the method created by the IDE has two parameters, sender and e. sender is an object and is a reference to the object that generated the event. e is the EventArgs (or a something derived from EventArgs).

With that in mind, the delegate created here will have sender and e parameters as well. But for the e parameter a new class will be created to store the specific details of the event.

public class ValueUpdatedEventArgs : System.EventArgs
    // Stores the new value.
    private string newValue;
    // Create a new instance of the
    // ValueUpdatedEventArgs class.
    // newValue represents the change to the value.
    public ValueUpdatedEventArgs(string newValue)
        this.newValue = newValue;
    // Gets the updated value.
    public string NewValue
            return this.newValue;
Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs
    ' Stores the new value
    Dim _newValue As String
    ' Create a new instance of the
    ' ValueUpdatedEventArgs class.
    ' newValue represents the change to the value.
    Public Sub New(ByVal newValue As String)
        Me._newValue = newValue
    End Sub
    ' Gets the updated value
    ReadOnly Property NewValue() As String
        Return Me._newValue
    End Get
    End Property
End Class

Next the delegate needs to be defined.

public delegate void ValueUpdated(object sender,
    ValueUpdatedEventArgs e);
Public Delegate Sub ValueUpdated(ByVal sender As Object, _
    ByVal e As ValueUpdatedEventArgs)

Now that the foundation of the mechanism for informing other objects of changes is written, the child classes can implement the raising of events so that observers (i.e. interested parties) can be notified when the value changes.

In the class for the child forms the event ValueUpdated is declared so that interested parties can indicate what they want to observe.

public event ValueUpdated ValueUpdated;

This is one area where C# and VB.NET differ. In C# an event requires a delegate, whereas in VB.NET the signature of the method to be called needs to be declared as part of the event. The advantage for C# is that the delegate only has to be declared once and it can be reused in many places whereas VB.NET has to have essentially the same bit of code, the method signature, rewritten frequently – this can be an area where there can be discrepancies between one class and another.

Next, when the child class is updated it needs to inform its observers (the interested parties, in this case it will be the parent and sibling forms). The following code shows what happens when the text is changed on the form.

private void uxMyValue_TextChanged(object sender, System.EventArgs e)
    // Get the new value from the text box
    string newValue = this.uxMyValue.Text;
    // Create the event args object.
    ValueUpdatedEventArgs valueArgs =
    new ValueUpdatedEventArgs(newValue);
    // Inform the observers.
    ValueUpdated(this, valueArgs);
Private Sub uxMyValue_TextChanged(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles uxMyValue.TextChanged
    Dim newValue As String
    newValue = Me.uxMyValue.Text
    Dim valueArgs As ValueUpdatedEventArgs
    valueArgs = New ValueUpdatedEventArgs(newValue)
    RaiseEvent ValueUpdated(Me, valueArgs)
End Sub

Now that the child form can inform others of the changes and what the changes are, the parent needs to open the child form and register as an observer so that it can be informed when changes are made. The parent will also ensure that other siblings that are interested get added as observers too.

private void uxOpenChildA_Click(object sender, System.EventArgs e)
    // Create the child form
    this.childA = new ChildAForm();
    // Add an event so that the parent form is informed when the child
    // is updated.
    this.childA.ValueUpdated += new ValueUpdated(childA_ValueUpdated);
    // Add an event to each child form so that they are notified of each
    // others changes.
    if (this.childB != null)
        this.childA.ValueUpdated +=
            new ValueUpdated(this.childB.childA_ValueUpdated);
        this.childB.ValueUpdated +=
            new ValueUpdated(this.childA.childB_ValueUpdated);
Private Sub uxOpenChildA_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles uxOpenChildA.Click
    ' Create the child form
    Me.childA = New ChildAForm
    ' Add a handler to this class for when child A is updated
    AddHandler childA.ValueUpdated, AddressOf ChildAValueUpdated
    If Not Me.childB Is Nothing Then
    ' Make sure that the siblings are informed of each other.
        AddHandler childA.ValueUpdated, _
            AddressOf childB.ChildAValueUpdated
        AddHandler childB.ValueUpdated, _
            AddressOf childA.ChildBValueUpdated
    End If
    ' Show the form
End Sub

All that remains is to implement the event handlers.

private void childA_ValueUpdated(object sender, ValueUpdatedEventArgs e)
    // Update the text box on this form (the parent) with the new
    /// value from the child
    this.uxChildAValue.Text = e.NewValue;
Private Sub ChildAValueUpdated(ByVal sender As Object, _
    ByVal e As ValueUpdatedEventArgs) Handles childA.ValueUpdated
    ' Update the value on this form (the parent) with the
    ' value from the child.
    Me.uxChildAValue.Text = e.NewValue
End Sub

And similarly in the child class.

public void childB_ValueUpdated(object sender, ValueUpdatedEventArgs e)
    // Update the text box on this form (child A) with the new value
    this.uxOtherValue.Text = e.NewValue;
Public Sub ChildBValueUpdated(ByVal sender As Object, _
    ByVal e As ValueUpdatedEventArgs)
    Me.uxOtherValue.Text = e.NewValue
End Sub

The code for this example is in the accompanying zip file. The project is called SiblingToSiblingCS (for the C# version) and SiblingToSiblinVB (for the VB.NET version)


It is quite simple to pass values from one object to another. In some instances it does take a little bit of effort to get it done right. Especially as it is all too easy to couple forms together that really shouldn’t know about each other.

©2005 Colin Angus Mackay. All Rights Reserved – The only authorized websites that may show this article are CodeProject, and Developer fusion.