Thursday, January 29, 2009

This shouldn’t be that hard!

For any of my vast number of readers (hah, hah) who have been following this blog, this post is more what I intended when I decided to start blogging, but so far, haven't gotten around to – a recounting of dealing with a technical issue.

So if you're not into software development, this will doubtless leave you cold, and you're forgiven if you want to go read something more interesting.

For the past 3 days I have been struggling to do something in Microsoft ASP.NET that should be duck soup. But it ain't.

I have a 24x7 array of data that I want to present and edit in a GridView.

Now, a GridView being a presentation control composed of a number of rows and a number of columns, one would think at first glance that he could simply set the DataSource to the array, and, voilá, it would appear. Not so.

In the end, the solution is not too, too terrible, but arriving at it is. This is owing in large part to the state of documentation of today's software products.

They come with megabytes and megabytes of hyper-linked references and how-to walkthroughs, which is great if the task you want to accomplish is exactly one of the walkthrough topics. But if not, you're left to try different combinations of words in various online and offline search engines and hope you hit a combination that lands on an article that somebody has fortuitously written that describes your plight, or something relevant to it.

Now, the Visual Studio Help file entry for "GridView" tells you:

The GridView control can be bound to a data source control (such as SqlDataSource, ObjectDataSource, and so on), as well as any data source that implements the System.Collections..::.IEnumerable interface (such as System.Data..::.DataView, System.Collections..::.ArrayList, or System.Collections..::.Hashtable).

(An IEnumerable is basically anything whose members you can sequence through one at a time – including an array.)

But then it goes on and tells you that there are two different ways to bind to the datasource, depending on which type you're using – a data source control, or an IEnumerable. And there's the first hint of difficulty.

The GridView is really designed to work with data from a database, and when you use it that way, everything just goes, point, point, click, click, and it just works. But when you start trying to figure out how to use it with arrays, you're just kinda left in the dark. Searching help files for "GridView binding to array" yields a bunch of articles and hyperlinked references on binding GridViews … to DataSource controls. I never could find a walk through on how to use it with an array.

When you bind to a Database data source (from now on referred to, as Microsoft does, as a "Data Source Control"), the binding goes in the aspx declarative markup, so it's there automatically each time the page is loaded. When you bind to an array, you have to set it programmatically, which basically means that you end up starting all over each time the page is loaded, including when anyone clicks on a button or link on the page.

I'm gonna cut to the chase here and skip dragging you through all the stumbling around that I did … partly in the interest of time, partly so I don't make myself look excessively stupid.

Yes, GridViews can be bound to arrays, although, at least not that I could find, to 2-dimensional arrays, at least not in the way that I wanted to. The thing is that you have to do everything just right, and if you don't, you're rewarded with … nothing. It just simply doesn't work, and you have no clue why.

The first thing is that, while a GridView looks like it would display a 2-dimensional array nicely, it really displays a one-dimensional sequence of objects (in its rows). The columns that it displays have to be Properties of the objects. Not just elements, but properties. Thus, one of my early attempts, for a programming exercise, involved an array of product elements:


public
class
shortProduct

{


public
int id;


public
string sku;


public
string name;


public
decimal cost;


public
bool fractional;


public
decimal weight;

}


I tried to bind an array of those to a GridView (actually, that was a Windows Form project, so it was a DataGridView, but it's the same principal), and got nothing, because those elements (id, sku, etc.) are just elements and not properties. When I converted them all to properties, and bound it to the control, they came up pretty as you please.

But that's a problem when you have a 2-dimensional array of simple elements. What I ended up doing was re-mapping it to an array of 7 objects, each of which was an array of 24 booleans. And then I defined 24 separate properties corresponding to each one of the Booleans. Now I could display it in a datagrid. Clumsy, but it worked:

public class ValidTimeDay

{

private bool[] _validTimeArray;

public bool ValidHour0 { get {return _validTimeArray[0];} set { _validTimeArray[0] = value}}

public bool ValidHour1 { get {return _validTimeArray[1];} set { _validTimeArray[1] = value}}

etc. down to

public bool ValidHour23 { get {return _validTimeArray[23];} set { _validTimeArray[23] = value}}


}


Now I had an object I could display in the GridView. I then mapped each of the 7 rows into one such object, and made the 7 objects into an array, and I could bind to it.

The other area where the GridView makes it difficult to work with arrays is in the editing features. Again, when you're working with Data Source controls, enabling editing of the data is pretty much point, point, click, click. Because the array doesn't have any kind of programmatic insert/update/delete interface, the GridView basically throws up its hands and leaves it up to you. You can get an Edit button on your GridView with just a few clicks, but everything else is up to you. You have to write the program code for handling each event in the process. And one thing that cost me about half a day of stumbling around until some kind soul on a forum gave me an example, the first thing you have to do is tell it what it's editing – even though it just told you . In your "RowEditing" event handler, the first line should be something akin to "GridView1.EditIndex = e.NewEditIndex". If you don't do that, nothing else happens! You also have to write the code to go back into the child controls of the GridView and figure out exactly what changes were made and store them in the array- that doesn't happen automatically either.

Once you know how to do something, it's not all that hard. It just shouldn't be that dang hard to figure out.




Monday, January 19, 2009

My first cruise




I’m writing this in the car on the way back from my first cruise. It’s something I’ve wanted to do for a long time, and let me say, right up front, I’m glad I went and I had a good time.

But it didn’t really meet my expectations, and I doubt I will go again. The problem may have been with my expectations, or it may have been with the cruise.

For one thing, at least in my mind, when one says “Caribbean Cruise”, one pictures, well… a CARIBBEAN cruise. Caribbean as in, primarily, warm, and with white sand beaches and blue water.

We left Dallas at 6:30 in the morning with the temperatures in the 20s. And while the cruise was certainly warmer than we left in Dallas, it didn’t match up with my mental picture of WARM. But I should have realized, even though we’re going to the Caribbean, we’re starting the voyage from Galveston, a scant 300 miles south of Dallas. Plus the same cold front that had sent temperatures plummeting in Dallas had pushed its way on south. While the temperature as we boarded the ship was in the 50s, there was a stiff north wind that kept me in sweatshirts and jackets nearly the whole trip.

So I guess the lesson to learn from that is, don’t plan a cruise out of Galveston in the middle of January if you’re expecting warm weather!

That same wind kept the seas rough. The ship was rolling from side to side, to the point where I had the sensation that I was going to roll right out of the bed. While I’m usually pretty good about motion sickness, by 3:00 PM of our first full day at sea, I was huddled in bed to keep from hurtling my lunch. Nancy, my girlfriend, went to the infirmary and brought back some motion sickness pills, which alleviated the sensation, but also virtually knocked me out till 8:00 the next morning.

The consolation, though, is that several cruise veterans said that was the roughest they had seen the seas on any of their cruises. So if I were to go again, that experience probably wouldn’t be repeated.

Overall, the cruise was very relaxing and enjoyable. I got to see a couple of beautiful sunrises (see photo) and sunsets over the water. The food was plentiful, and was certainly good, though I wouldn’t consider it superb. About on a par with what you would expect from your typical casual dining restaurant. However, the claim I have often heard that you can find something to eat at any hour of the day or night turned out to be not quite true, unless you count soft-serve ice cream. We went in search of some at 4:00 one morning, and the ice cream machine was about the only thing we found stirring.

While the weather in Cozumel was somewhat warmer (mid 70s), the same wind still dogged us, and it was cloudy, so I wasn’t really inclined to hit the beach with the few hours we had in port.

While there were certainly enjoyable activities on the ship (dancing, clubs, shows, parties, etc.), I guess I would much prefer, if I’m going to a Caribbean destination, to get there and spend the time on the beach or in the water, rather than spend a day and a half at sea (even if it’s enjoyable) each way to get a few hours at the destination.

But, at least I got to go, and that’s something I can cross off my list of things I’ve always wanted to do!