The first thing I noticed about the newer visual studio (2005) was that many of the automated tools (such as databinding) now worked. This doesn’t mean that it always works flawlessly, but that you can generally make it work. There are enough events and places you can hook into (not to mention writing your own sub classes) that you can generally find a way to get the behavior you are looking for. Unfortunately, this means that using automatic tools can result in you writing 100’s of lines of code (at times enough that you could have written less code if you had done things manually). Once case I came across the other day was with an ImageColumn in the DataGridView control.
My needs didn’t include binding the image directly to a fields (e.g. storing the image in the database). I just wanted a delete image to show up that could be clicked since I chose to hide the row header (that thing that shows the pencil or asterix and takes up about twice as much room as it needs too). First, I use the point and click interface to set the image for that column thinking, wow, this is easy. In true Microsoft style, instead of showing the image I picked, the column completely ignores the image I specify and shows the broken link image instead. My search for a solution began.
I found that by default, the ImageColumn would set itself to the broken link image. Apparently its by design, though I can’t understand why when you explicitly set the image using the GUI tools. There were two main solutions presented for this problem. Neither were satisfactory to me, but I will include them here to be complete (they may be a better fit for you).
The first solution is to set the default NULL style for the ImageColumn before it is rendered. Apparently this will make it use our “default” image rather than the broken image. With this solution, the column is still behaving badly, but its bad behavior happens to align with your wishes now. I would have been fine with this solution (as all rows should have the same image) had I been able to make it work. For me, this didn’t seem to work (still showed the broken image). I am sure this CAN work if you do it right since I found the same solution in several different places.
The second solution is to write your own ImageColumn class and inherit from the existing class. You can override one of the Format events and return your image. While writing your own class and inheriting from the ImageColumn class is a great feature (in fact that ability is one of the reasons that the databinding in .NET 2005 is considered a viable option now) it seem a little overkill. You see, the ImageColumn is supposed to be able to do what we want… show an image in a column! It seems a little excessive to have to go through all that just to get an image to show when the original class was built to do just that.
My solution is to just hook into one of the many events available and assign the image to the column explicitly. This allows you to also handle each row on a case by case basis (for those of you who might want a different image for each row). The article about writing your own class tipped me off. If you inherit the ImageColumn class just to override a formatting method, why not just use the formatting event in the DataGridView control? Below is the code that I use to set my own image.
The event is called for EACH and EVERY cell displayed. Since my delete button is supposed to be in the first column, I use the column index to see if it is at position 0 (the first column). If it is, it must be one of my delete buttons. The 2005 edition of the .NET framework has some great shortcuts under the My namespace. All your resources (in this case my bitmaps) can be easily accessed via the My.Resources object. This make it extremely easy to pull that image and pass it to our ImageColumn.
Microsoft consistently does an excellent job and a terrible job of designing its programming tools. The parts that work, work great. The parts that don’t, are horribly written and often not worth using. This has changed in the .NET framework due to the fact that they have done a good job enabling you as the programmer to fix or code around things that are broken or that don’t have the features you need. Beware though that you don’t get caught up implementing the complicated solutions when there are simpler solutions out there.
Computer Magic And Software Design