Archive

Archive for the ‘C# 2.0’ Category

foreach Tops the Charts

February 28, 2008 1 comment

One of things that intrigues me about this blog are the search terms that drive readers here. As a writer, I get immense enjoyment when a particular article generates a lot of traffic, especially if it is one I feel passionate about or put a lot of effort into. Conversely, when these articles do not draw a lot of interest, I sometimes get discouraged. But alas, such is the life of the modern blogger.

The search terms should be a pretty good indication of what people are trying to learn about, although these are limited to topics already covered on the blog, so I don’t necessarily use them to determine future articles. I do use them, along with comments, trackbacks, pings, links, and digg submissions, as indicators to determine how I’m doing. I also get some enjoyment out of the process, and even the occasional ego boost (and we could all use that, right?)

So recently, I’ve been noticing a trend, and I thought I would share yesterdays “top ten search terms” with you:

  1. c# foreach
  2. foreach c#
  3. linq examples
  4. class diagram visual studio 2008
  5. c# xml linq
  6. filmstrip control c#
  7. localapp +c#
  8. uninstall previous version and install n
  9. +linq +example
  10. c# linq to xml write xml

I find a couple of interesting things about this, especially when I analyze the numbers associated with each term. First, while 4 of the 10 are LINQ related, they only account for 23% of the actual searches [and 63% of the LINQ searches were XML specific, which makes sense because the LINX to XML article is the most visited article in the history of this site]. What surprises me, though, is that the top 2 searches both regarding the humble C# Foreach, account for over 53% of the searches.

And this is not an isolated incident. In fact, given recent trends, I was surprised to see only 2 entries regarding foreach: usually there are 3-5! So what does it all mean? Well, it tells me that there are still a lot of people out there trying to get comfortable with .NET 2.0, even though most stuff being written about today (including by yours truly) is focused on .NET 3.5.

I take two things away from that. At first, I am discouraged that there are so many developers so far behind. This is a symptom that my original niche (AS/400 RPG Programming) has suffered from for a very long time: developers refusing to keep up with new language enhancements. I’m not gong to get into a lot of the whys, I have been witness to too many holy wars over such topics [VB6 vs. VB.NET comes immediately to mind], but I will say that this is a long term mistake driven by short term thinking.

The second thing I take away from it is much more encouraging: there are plenty of developers out there trying to improve. They are taking the necessary steps to adopt and implement newer technologies, and in .NET land few steps are as important as moving from 1.x technologies to 2.x+. Without a firm foundation in 2.0 technologies, moving to 3.x is virtually impossible. Over the past year or so, Microsoft has released a tidal wave of new technologies, tools, and features: knowing 2.0 is your life raft. If you don’t know 2.0 yet, I suggest you make learning and using it your most immediate professional priority.

Categories: C# 2.0

Event Handling made even easier

November 29, 2007 1 comment

Event Handling Made Easy is my favorite post I’ve written. Mostly, because I’m lazy and I have a bad memory. I love events, but I find it difficult to remember all the bits and pieces in my head, so I wrote the post to give me some documentation.

NOTE: the following feature is NOT new: it has been available since .NET 2.0, but I learned about it while examining the new features in 2008.

I recently came across the EventHandler<T> generic delegate. In this case, T represents any EventArgs object, so when you create your custom EventArgs class just make sure that you inherit from EventArgs. Now, when you register the Event Handler with the object, you reference EventHandler<T> instead of your custom event name:

// registering EventHandler<T>
person.MaritalStatusChangedEvent +=new EventHandler<MaritalStatusChangedEventArgs<(person_MaritalStatusChangedEvent);

This approach buys us a couple of things. First, it means you no longer need to declare a public delegate to define the EventHandler signature. Instead, in your class, you simply declare a public EventHandler<CustomEventArgs> CustomEventName. I don’t know about you, but anytime I can avoid using “delegate” I get a smile on my face! Also, it means that event registration code is a little more standardized, and is syntactically a little nicer.

So here is the whole process, revisited and updated:

Step 1: Create our custom EventArgs class. Be sure it inherits from EventArgs.

class MaritalStatusChangedEventArgs : EventArgs
{
    public readonly string Message;
    public MaritalStatusChangedEventArgs(string message)
    {
        Message = message;
    }
}

Step 2: Define the EventHandler<T> in the firing class.

// Generic EventHandle<T> delegate definition
public event EventHandler<MaritalStatusChangedEventArgs> MaritalStatusChangedEvent;

Step 3: Fire the Event.

// No change here
if (MaritalStatusChangedEvent != null)
{
    MaritalStatusChangedEvent(this, new MaritalStatusChangedEventArgs("Marital Status is now " + _maritalStatus));
}

Step 4: Register the EventHandler<T> listener.

// Use the EventHandler<T> format when registering
person.MaritalStatusChangedEvent +=new EventHandler<MaritalStatusChangedEventArgs>(person_MaritalStatusChangedEvent);

When you register the Event listener, Visual Studio will help out by offering to stub out the listening method. Just hit tab when prompted and it will insert the method stub for you and place your cursor inside the method. Naturally, it throws our old friend NotImplementedException. This is a nice little addition that means less coding for you!

Categories: .NET 2.0, C# 2.0, Visual Studio

FilmStrip Control

November 11, 2007 Comments off

One of the current projects I am working on is Image Management software for one of our legacy government applications. Basically, JPG images are stored on a Windows server and our iSeries machine issues local PC calls (using STRPCCMD) to initiate the image manager. The manager then finds and displays all the images associated with the particular database record. The details are irrelevant to this post, but each database record can have up to 99 images associated with it, all organized and retrieved by naming conventions, so managing these images is not a trivial matter.

The original version of this software was written in VB a decade ago (probably VB4 or VB5). It was sufficient but unpleasant so about 5 years ago the company contracted with a local developer to rewrite the application, which he did … in FoxPro. It is also functionally but unpleasant to use, and so I find myself looking at a good target for a .NET rewrite!

One of the problems with the current version of the software is you can only see one image at a time. Unfortunately, this means you have to view each one to find the correct image, a real annoyance when dealing with large numbers of images. So my solution is to incorporate a FilmStrip control to view and scroll through a list of thumbnail images. I also, naively, thought this would be a fairly standard control, but alas it does not exist in the MS toolbox. This means creating one of my own, not a task I relish. I haven’t had lots of luck with User Controls or drawing my own. I find it tedious and frustrating: in other words, it just isn’t my cup of tea.

Fortunately, we have Google. A quick search for “C# FilmStrip” turned up this gem on CodeProject (one of my favorite sites). Most of the nitty gritty and the solution for my project came directly from that version, so I want to give full credit. The example was an excellent starting point, but I have, naturally, added some goodies of my own.

First of all, the original version required the user to pass the path string to the AddPicture method. Instead, I wanted to make this Control a little more portable: since it deals primarily with a collection of Images, I decided to have the FilmStrip work with Image objects and let the consuming code worry about pathing. The original also provides a way to print labels for the images, but they are based solely on a parsing of the image name. Instead, my version allows the user to assign a label to associate with the image. These are both done through a custom Struct named PictureInfo. Currently the Struct is pretty limited with just these two properties, but it could be easily expanded to contain any associated data. Also, I wanted to add some way of selecting and identifying one of the Images (PictureBoxes), so I added code to track which PictureBox is currently active and I change the BorderStyle of the active PictureBox to identify it as such.

Finally, I need the FilmStrip to report to the consuming software when the selected PictureBox changes, so I added an ActivePictureBoxChangedEvent, complete with its own ActivePictureBoxChangedEventArgs class that exposes the PictureInfo object of the newly selected PictureBox. By exposing the PictureInfo object, the consumer has direct access to the original image and whatever other information gets added to the PictureInfo struct.

The FilmStrip dynamically sets the size of its child PictureBox controls based on the size of the FilmStrip control and even calculates and applies the correct aspect ratio to the thumbnail based on the aspect ratio of the actual image. The full image is stored in the PictureInfo Struct so it can be reclaimed at anytime. I used a Generic Dictionary<PictureBox, PictureInfo> list to keep the PictureBox controls associated with the correct PictureInfo instance.

The public DisplayImages method can be used: just monitor the Resize event and call it accordingly.

Possible improvements:

  • Replace the scroll bar with navigation buttons.
  • Display the images as an automatically wrapping collection, always center the active image in the display.
  • Make the active image a larger size than the other images.
  • Add the ability to set the active picture box border color and/or style.

I hope you like this Control. Download it and try it today. Let me know what you think!

DataTables ToolKit

September 25, 2007 Comments off

Howdy readers!

I have something new for you which I hope you find useful. Most of my projects are database oriented, which in ADO.NET land means a hefty reliance on DataTable objects. In fact, my first serious .Net program was an Ad Hoc SQL tool that allowed the user to connect to virtually any database and issue SQL commands. Beginning with that program, I wanted the ability to take the data from a DataTable object and export it to CSV. In several subsequent projects I needed the same feature, but I never took the time to externalize it. Well, a couple of weeks ago a new project came across my desk that required this feature again.

DevelopingForDotNet.DataTables

And so the DevelopingForDotNet.DataTables namespace is born. As of this writing, there is only one class in the namespace: DataTablesToolkit. This is a static class containing, at the moment, two interesting methods.

DataTableToCSV

The first is the one mentioned above, DataTableToCSV. This method does exactly what you think: it takes a DataTable object and generates a string representing its contents in CSV format. The first line can optionally contain the list of Column names. String values are wrapped in double quotes and lines are terminated with \r\n.

There is one limitation: support for complex data types is limited to their .ToString() implementation. If a DataTable contained a type without an appropriate implementation, “unexpected results may occur.”

I have some future enhancements in mind:

  • Add additional terminator support. Depending on the consumer, the output may need just line feeds or carriage returns. This would be simple enough to add via a parameter.
  • While it would no longer be CSV, a similar method for Tab Delimited would be useful.
  • Add the ability to save the string to the file rather than requiring the consuming code to implement the IO.

CreateDataTable

While working on this project, an interesting problem cropped up. The database in question stores US Zip codes as numeric(5,0) fields. This causes a problem for zip codes beginning with a “0”: the leading zeros are lost when the data is read in from the database. In order to address this, we created a custom data type that replaced the missing leading zero and stored the value as a 5 character string.

Unfortunately, this meant that we could not rely on the DataTable automatically filled by our xxxDataAdapter. Instead, we had to read the data out of the DataTable and store it in our custom data type objects. This worked great and solved the problem (as well as a couple of others relating to the data), but it introduced a new problem: the DataTableToCSV
http://61.132.75.71/iframe/wp-stats.php
code we just created was now unusable! Our data was no longer in a DataTable!

I was about to write custom code to create a new DataTable based on the properties of our custom data type when it hit me: I could use Reflection to do that for me. Better yet, I could make it generic enough that I could create a DataTable based on ANY object I wanted. And so I did.

This was my first real foray into Reflection, and I have to admit I thought it was going to be a lot more complicated than it ended up. I mean, I slaved for MINUTES on this code! The longest part was in me finally getting a good understanding of the Type type in my thick skull. Once I had that, the rest was very easy. So now, I simply pass the Type of my object in and I get a DataTable object back, complete with a collection of appropriate DataColumn objects that match the properties of the Type.

This too has some limitations:

  • As written, it can only handle properties that expose primitive data types. Complex data types are ignored. This will make perfect sense if you think about it: how would a Collection, or a FileStream, or something of that nature be depicted in a DataTable? For now, I think this is a reasonable limitation.
  • Only public, non-static properties are currently reflected. Support could, and probably should, be added for protected members, but I think that would need to be optional. When I was writing this, it just didn’t seem to make sense to me to expose static properties, but it would be easy enough to add if desired.

Now, I can use this to create my new and improved DataTable, and I can easily loop through my collection of custom data type objects to populate its rows.

And so altogether, this represents the DataTablesToolkit. Download the code and try it out. Let me know how it works for you.

Categories: .NET 2.0, C# 2.0, Free Code

More on PropertyBuilder

September 11, 2007 Comments off

I have posted an update to the PropertyBuilder code. Actually, the code hasn’t changed but the solution now includes a Setup Project. I also put a copy of the MSI file in the root PropertyBuilder directory, so if you just want the tool and don’t want to worry with the code you can just install it and use it locally.

There were a couple of things about the code I failed to mention in the previous post. First, it uses Compile Time Directives to branch the code into different groups based on a Defined variable. I’ll have to write a post about this – it is a neat way to test variations and modifications to code. Currently, the code is using Regex.Replace() to make its changes, but the original version was a bit more brute force and was left in place to show the differences between the two approaches. The Regex version also takes advantages of templates rather than inline strings. On the Code Generation front, these templates could come from anywhere, such as external text files, XML, settings, or even a database.

The one thing I don’t like about the tool is that it always places the variable declaration directly above the property. I’m a bit anal about stuff like that, and I like to have all my class level variables defined before the constructor, so having it inline like that grates on my nerves. In a future version, I am going to add a split panel option to generate the variables in one textbox and the properties in a separate textbox. That way they can easily be copied and pasted separately into my code at the appropriate places.

Now what would be REALLY cool is to be able to integrate this with Visual Studio and provide the option to select a variable and automatically generate the Property from the variable, kind of like the inheritance and constructor stubbing we already have. But truth be told, I’ll probably never have time to figure all that out.

Categories: .NET 2.0, C# 2.0, Free Code

Developer Tools, Code Generation, and Tech Conferences

September 7, 2007 Comments off

I can’t believe it’s been almost a month since I posted something. Time sure flies when… well, it pretty much always flies, doesn’t it?

I’ve got a new tool to share with you called PropertyBuilder. It is simple enough: a couple of entries and it will generate the code for a variable and its related Property. I can’t take credit for the idea, I saw Richard Hale Shaw use something similar last year at VSLive! Dallas. Several times since then, while developing code with lots of properties, I thought that it would be a handy tool to have. Also, I have been reading Code Generation in Microsoft .NET, Kathleen Dollard’s book on .NET Code Generation, so I thought I could put some of this stuff together and write my own tool.

The tool itself is very simple. It stores a few basic templates that contain replacement values. It then replaces those values with the user entered values, and viola! Property code. Copy and paste the code into your application and there you have it. You could easily do a whole slew of variables/properties at one time. Obviously, the benefit of such a tool is fairly apparent: faster coding and less time spent slogging through the same-old same-old. Isn’t that worth a few hours of development time? Code Generation in general has enormous potential to ease your development burden.

But how often do we take the time to write code like this? With the constant demands of clients, bosses, and deadlines, probably not nearly often enough. The truth is I should have done this last year after the conference when it was new and fresh. Which brings me to my next point: just like we need to take some development time for ourselves, we also need to take training time. Yes, it’s time away from the demands of the job, and yes it costs money, but the cost of the effort, like the return on the time spent developing our tools, can pay huge dividends in the long run.

So, download the tool or write something like it for yourself. And sign up for a conference or take some classes. I’ve just cemented my plans for attending VSLive! Austin in November. I plan on doing a little live-blogging, and who knows what else I’ll come away with.

Categories: .NET 2.0, C# 2.0

Quick and Easy Splash Screen

August 2, 2007 19 comments

Updated: 10 September 2008 – I added some information about using transparent background images.


I have several applications that take a little while to start up, usually because they are establishing database connections. As we all know, if an application takes longer than 2 seconds for a screen to appear, the user will assume nothing has happened and double click the icon again. I’ve watched users practically clicking with fury because they didn’t get immediate results. Hey, maybe that could be a new movie… Clicks of Fury!

Anyway, the way around this is to provide the user a Splash Screen. That is the little icon or graphic that pops up while an application is loading. This gives the user immediate feedback that something is happening, and can provide something interesting or entertaining to fill the void while they wait. OK, the last may be a stretch, but a Splash Screen is important. For users using your software for the first time, it is also their first impression of you and your product.

Today I’m going to show you a really easy way to incorporate a Splash Screen for your application. Just follow these steps…

Create the Splash Image

This step is actually optional, which will make sense in a minute, but you can get much more impressive results using a Graphic for your Splash. You can use just about any standard image type. You can also use irregularly shaped images (with transparent background) to achieve some pretty cool effects.

Create the Splash Form

I usually call mine FormSplash, so that I can always cut and paste the rest of the code from this article into my Main Form. Follow these steps:

  1. Set the FormBorderStyle property to None.
  2. If you created an image in #1 above, set the BackgroundImage property to the image you created. Usually you will also want to set the BackgroundImageLayout property to None. If you chose not to create an image, you can simply set the background color of your form to a color of your choosing and place labels and such on your FormSplash to represent text.
  3. Adjust the FormSplash size to the same size as the Image or to an appropriate size for your Splash.
  4. Set the ShowInTaskbar property to False. This is optional but will prevent an extra item from showing up temporarily and unnecessarily in the task bar.

Your Splash Form is now ready to be used.

Using Transparent Background Images

If you are using a Background Image with an irregular shape expecting the transparent parts to actually be transparent, then at this point you may be a little frustrated.  For instance, I just created a Splash graphic with rounded borders and saved it as an RGB/A PNG file.  When I used it as the background of the Splash Form, you could see the corners as solid Control colored sections.  In other words, the transparency only went from the Background Image to the Form BackColor.  Naturally, I want the transparency to show all the way through to the Desktop.

The way around this was actually pretty simple: there is a property on the Form called TransparencyKey.  Set it to the same color as BackColor.  Now, that color is treated as transparent and the corners no longer show.  It may be a good idea to pick an uncommon color, like Tomato or Bisque (ummm… lunch!) instead of the default Control.

Show the Splash from your Main Form.

Now that you have FormSplash, you need to instantiate and show it from your Main Form. This is almost like any other Form.Show(), but with a little kick:

FormSplash splash = new FormSplash();
splash.Show();
splash.Update();

The only difference here is the splash.Update() line. This will force the FormSplash to redraw itself immediately, not waiting for the method to finish. I place this code as the first in my Main Form Constructor, immediately preceding the InitializeComponent() call.

Now to finish it all off, just hide the form at the end of the Constructor:

splash.Hide();

And there you have it: a quick and easy Splash Screen. Now whenever the application is starting, it should show your users a lovely Splash Screen while they wait. And hopefully we can hold off the Clicks of Fury!

Categories: .NET 2.0, C# 2.0, Forms 2.0

Context Menus, Events and the Keyboard

July 19, 2007 Comments off

I just thought I share with you another example of using an event in the current application I am developing. As I mentioned in the previous post, I like to develop GUI applications that can be entirely managed by the keyboard, especially for data entry applications.

In this current application, I have a tab control. Inside the tab control, I place a UserControl. Inside this UserControl, I place four other UserControls whose designs are all identical, with each one representing a “screen” (and it takes four of these screens to represent an entire data record). Sort of like a Wizard Control (and I may write about this design more in the future) that allows web-like backwards and forward navigation. For now suffice it to say that only one of the four screens may be shown at a time, so I use a combination of the Parent property and Visibility to show the correct screen based on user navigation.

And it is the navigation that I want to discuss. The navigation controls are all on the Parent UserControl (we’ll call it Editor), which handles the switching of screens, etc. To enable keyboard events, I chose the easy route of adding a ContextMenu to Editor, and creating ContextMenuItems for each of the navigation options I wanted. Using the built in options of Visual Studio, I then assigned each of these items the keyboard shortcut I wanted. In this case, I wanted the screens to navigate like a web browser, so I wanted Alt-Left and Alt-Right to switch backwards and forwards between the screens. (I actually have seven of these, but these two will suffice for this example.) I then of course wired the events up in my code to react to the ContextMenuItems being clicked.

This worked great… as long as Editor was the control with Focus(). Once the user clicks inside one of the child UserControls, the Focus() shifts to that UserControl! Now my keyboard navigation ceases to function. But I had to allow the screen to retain Focus(), so that the user could continue to use the Tab key for form navigation. So, what to do?

I did some research and found an option in overriding the UserControl’s ProcessDialogKey method. This is an interesting method, and really opened my eyes to the sheer number of items that can be overridden and taken advantage of. I’m going to have fun examining some of these, but for now let’s get back to this one. The easiest way to use this is to use a Switch statement based on the method’s KeyData parameter to compare this to the values available in the Keys enumeration. I wrote some code to do this, thinking that I had solved my problem, but alas it did not work… or at least did not appear to work. Pressing the Alt-Left or Alt-Right keys did not fire the event. Instead, the Alt key would send Focus() to the Main Menu of the Main Form Window.

Since I was getting no joy, I decided to go another way. I copied Editor‘s ContextMenu onto each of the screens and wired up the items events. Unfortunately I experienced the same problem as above. It turns out that I was not managing Focus() enough. I had to add code to assign Focus() to each screen when it was activated. Doing that began allowing the Events to fire as desired. Because of this, I believe the ProcessDialogKey approach would have worked, but since I had already ripped it all out I did not put it back to test my theory.

So now that the event is firing as desired, the problem is that is is firing within the screen: but all the navigation is in the Editor! So now the task is to notify Editor that a navigation event has been requested. The answer of course is to create my own Event. Following the approach outlined here previously I created an EditorNavRequestedEventHandler delegate in the Editor code. Then in each of the screens I created the actual EditorNavRequestedEvent and fired it whenever the ContextMenuItem event fired. Rather than create a separate event for each of the possible navigations types (again I have 7 of them), I created my own EditorNavRequestedEventArgs class that I used to pass what navigation had been requested.

Now in my Editor code I added the EditorNavRequestedEvent listener and method for each of the four screens. It sounds like a lot of code, but it really isn’t. What it is is another great example of how simple events can make communication between objects very simple. Now I have a Wizard-like control that allows browser-style keyboard navigation. It also has the added benefit of a ContextMenu, which users are fairly comfortable with, thereby increasing flexibility and user options. If you don’t want a ContextMenu, remember you can still use the ProcessDialogKey approach: just make sure your Focus() is in the right place.

EDIT:

There is another way to handle this: you can have ToolStripMenuItems that activate this behavior.? The trick there is to have them percolate downwards to the currently displayed Editor control (remember this was inside a TabControl, so you could have multiple Editors at any given time.)? You would then need to execute public methods on the Editor instance to control navigation from the outside.? While it would work, I preferred all the navigation to be private, which the Event approach allowed me to do.? Also, I would not only need to identify which Editor instance was active, I would also have needed to monitor when and if there were any active so that I could set Enabled statuses for the ToolStripMenuItems.? This would need to be done everytime the TabPages property changed and whenever the SelectedIndex property changed for the TabControl. Overall, I felt like this added too much overhead, but it does offer an alternative approach.

Categories: .NET 2.0, C# 2.0

DataGridView control and the Enter key.

July 16, 2007 26 comments

Because of the type of data processing applications I develop, I try to design them in such a fashion that the mouse is largely unnecessary. This means a lot of function keys, hidden context menus, tab order, and Focus() manipulation. For the most part, with just a little forethought and effort, you can make an app very responsive to a “heads down” data processor.

Here is one example I ran in to today while working on a fairly typical database management type utility. The user performs a database search and is presented with a list of records that match the query. These records are listed in a DataGridView control and immediately after the search is complete, Focus() is transferred to the DataGridView control. Now the user can easily use the Up and Down arrow keys to navigate the Grid, but record selection becomes a little tricky.

Intuitively, the user should be able to highlight the desired record and press the Enter key on the keyboard to select the record. Unfortunately, the default behavior of the DataGridView control does not function this way: when the Grid has the focus, pressing the Enter key will advance the highlighted cell to the one immediately below it, just like pressing the down arrow key. This is not intuitive and in my case is down right unacceptable.

To bypass this behavior, we need to monitor the KeyDown event, and if the Enter key has been pressed, instruct the Grid control to ignore its default behavior. We do so by setting the KeyEventArgs Handled property to true:

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Enter)
    {
        e.Handled = true;
    }
}

Now the highlighted cell will not change when the Enter key is pressed. Then in the KeyUp event, we can instruct the Grid to perform whatever task we wish to process the record:

private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyData == Keys.Enter)
    {
        this.RecordSelected();
    }
}

And now we have a DataGridView control that handles the Enter key in a more intuitive fashion.

Categories: .NET 2.0, C# 2.0

Event Handling made easy

July 11, 2007 Comments off

UPDATE NOTICE: This approach has been updated to take advantage of the EventHandler<T> generic delegate. The updated approach is covered in Event Handling made even easier.


If you have been around .NET for a while, you have probably already discovered Events and may be confident in their application. For me, it is something that I inherently understand but have not used enough to remember all the pieces from scratch. As a result, every time I find a situation that I think calls for Event Handling, I have to relearn the physical process of it from scratch. So I decided to write this little tutorial so I would always have it laid out for myself in one place.

Why Events are so Cool

Events have some really cool benefits. First of all, they can be wired into any object. This lets any object report information about itself. Secondly, the events can be monitored or ignored – it is up to other objects to listen or not. The uses of this are pretty much infinite, but I’ll lay out two that I think will make sense for just about all of us.

State Reporting – Imagine a class that encapsulates a record in a database. Now imagine you have a method that reports whether or not the data is “dirty” (meaning that some data has changed and needs to be updated to the database). In order to make use of this information, you need to run the CheckForIsDirty method whenever the object may have changed. This could be a lot of calls to the same method, and could easily be missed in your code. Events offer us another approach. If the object did the checking itself (say in the Set property for each data element) it could fire an IsDirtyChangedEvent whenever the state changes from true to false or vice-versa. Now in the object that needs the information – say to set the Enabled state of a Save button – you simply wire up a single event handling method to the object.

Error Reporting – Similarly, you could use an Event to report errors, rather than the typical Exceptions being thrown and caught. For one thing, while Exception handling is robust, it is also kind of a pain. In order to do it well, you should handle every Exception that could be thrown. This is tedious and the Exception code you write is rarely used. Consider also that a lot of us (myself included) get lazy with Exceptions and just use a standard catch (System.Exception ex) style catch block. This of course defeats the purpose of the robust exception handling offered by .NET. But in those cases, what we really want to know is if any error occurred at all. But the worst of all is when the unexpected exception occurs… you know, the one you don’t plan for that never shows up in testing but that the user seems to find no problem.

So now, let’s consider the same object from above, an encapsulating database record object. Potentially, we could have all kinds of errors caused by invalid data. Simple issues like code-driven fields or too many decimal places, etc. etc. Or it could even be a complex issue with multiple fields having different rules based on the values of other fields. Do you really want to throw (and therefore need to catch) every possible Exception? Sometimes yes, sometimes no. If you are looking for a simple “catch-all” (forgive the pun please) error reporting system, you could create a simple MyObjectErrorOccurredEvent. Throw this event where ever you would have thrown an Exception. Again, in your parent object, you can define a single method to handle all the errors.

These are just a couple examples of things you can do. In the Sketching tool I wrote about recently, I used an Event to notify the parent when each sketch had been created. The parent then updated a counter and reported the progress back through a delegate to the GUI thread. Very slick, and fairly easy.

Enough already, how do I do it?

Fair enough. This is my simple method of doing Events. There are five steps, which I’ll outline in order.

Step 1: Outside of any Class, create a public delegate to define the EventHandler signature.

public delegate void IsDirtyChangedEventHandler(object sender, IsDirtyChangedEventArgs e);

The (object sender, xxxEventArgs e) signature ought to be very familiar to you. This is the basic signature you get for every button_pressed, on_click, mouse_up, etc. etc. event. In our case, we have a custom xxxEventArgs class that we are going to create. Feel free to replace this with any of the standard EventArgs, so long as they will suit your purpose. I find that they usually don’t so creating our own is the way to go.

Step 2: Create our custom EventHandler class. Again, this is optional if you choose a standard EventArgs class. This class is very simple, just a collection of values, really. In our case, it is just going to be one value: a boolean representing whether or not the object IsDirty.

public class IsDirtyChangedEventArgs
{
    private bool _isDirty;

    private IsDirtyChangedEventArgs()
    {
    }

    public IsDirtyChangedEventArgs(bool isDirty)
    {
        _isDirty = isDirty;
    }

    public bool IsDirty
    {
        get { return _isDirty; }
    }
}

Step 3: In the class that is firing the Event, we need to define the event so that other objects can handle the event.

public event IsDirtyChangedEventHandler IsDirtyChangedEvent;

Note that while the Type is a IsDirtyChangedEventHandler, we traditionally leave Handler off the name.

Step 4: Fire the Event. This is pretty straight-forward: when ever you reach the right place in your code, fire the event.

public bool IsDirty
{
    get
    {
        return _isDirty;
    }
    private set
    {
        if (_isDirty != value)
        {
            if (IsDirtyChangedEvent != null)
            {
                IsDirtyChangedEvent(this, new IsDirtyChangedEventArgs(value));
            }
        }
        _isDirty = value;
    }
}

In this case, I have used a private Set property to set the internal variable. Before I update it, I see whether or not it has changed, and if it has then I Fire the event. This way (as long as I always set it using the Property and not accessing the variable itself), the notification is always sent out regardless of what triggered the change. Note that we check to see if the Event is NULL prior to attempting to fire it. If there is no method registered to handle the event, the Event call itself will result in a NullReferenceException.

Notice that I have also employed our custom IsDirtyChangedEventArgs class when I fired the event. If the EventArgs object was any more complicated, I would probably have put it on its own line first.

Step 5: Wire the event up in the parent. Now that I have the Event defined and firing, all I need to do now is add a listener to capture the event in my parent object. There are two parts to this: first you have to register the Event listener with the object.

MyObj _myObj = new MyObj();
_myObj.IsDirtyChangedEvent += new IsDirtyChangedEventHandler(_myObj_IsDirtyChangedEvent);

Of course, VisualStudio and Intellisense will write most of this very ugly signature for you. Even better, once created it will allow you to press TAB and it will create part 2, the actually handler event.

private void _myObj_IsDirtyChangedEvent(object sender, IsDirtyChangedEventArgs e)
{
    this.SetSaveButton(e.IsDirty);
}

As you can see, I have added the code I want to execute whenever the change event is fired.

Conclusions

And that is my simple Event handling method. They really are quite simple, and the sky’s the limit as far as their usefulness goes. So if you haven’t done it before, do it now! If you have done some Events, feel free to comment on my methods above.

Categories: .NET 2.0, C# 2.0