Thursday, December 01, 2005

24.

{

24 ways is a new way to countdown to Christmas: web development tricks to impress your friends. This is worth a little application. Now the trick is just to apply some of these techniques instead of just linking to it.

The gnome behind it all is Drew McLellan. His blog is phat too.


}

Monday, November 28, 2005

Centered DIV

{

I'm used to the align attribute, but my recent CSS conversion has me doing things a bit different. Instead of table align="center" I've discovered the same affect with:

margin-left: auto;
margin-right: auto;


}

Tuesday, November 22, 2005

WinFX horizon

{

What does WinFX bode for smallfolk like me? At this point I'm given to think of Visual Studio 2005 and what sort of placement it will have in the product. I haven't done deep digging, but something tells me a WinFX designer is not going to be a part of Visual Studio 2005.

It goes back to my wariness of the concept of a "release cycle." Microsoft will reap another set of good earnings from a forthcoming release of a Visual Studio 2006 (or whatever) that has a WinFX designer for Vista's windowing system.

If you're designing a desktop application on .NET 2.0, what does this bode? Think hard about your strategy, and look over your shoulder at those slick COM applications.

I've posted on Joel on Software, hopefully someone will have a good response.

}

Get Executable Directory with .NET

{

What directory am I in again?

string dir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

}

Strip Time Off SQL Server Date Variable

{

DECLARE @DOUT DATETIME
SET @DOUT = CONVERT(DATETIME, CONVERT(CHAR(10), GETDATE(), 101))
PRINT CONVERT(DATETIME, @DOUT)

}

Wednesday, November 09, 2005

Technology or Tools, Visual Studio 2005

{

The big release is upon us. But it begs a question that I think those of us who use commercial development tools have to ask ourselves, something our Open Source brothers and sisters do not to the same degree. The question is whether we are driven by technology first, or whether we are led by tools.

Microsoft is driven to release products on a cycle that will earn them a consistent amount of revenue; sometimes the "new" product is hardly new at all.

Visual Studio 2005 looks good from my very preliminary browsing about, but I'm still approaching it with some caution. It's really cool to do "push button" refactoring, but is refactoring something we need to really think deeply about? A part of an underlying structure that must be designed carefully? Something that can't fix code that is already structurally defunct?

The class designer and snippets are cool too, but when I see the IDE eating up 800MB of memory on "Hello World" type projects, it makes me nervous.

My first stop is going to be new language features. After that I'm going to delve a little bit more heavily into the IDE. The ASP.NET features look good and somewhat different. But I'm a skeptic until I see the power for myself.

It's such a contrast to other worlds - to return to the idea of Open Source - technology there is more likely to evolve because of a need that must be met or a new idea. It is independent of the goons in sales & marketing.


}

Thursday, November 03, 2005

ASP.NET Control Trees

{

Debugging a problem today I wrote this, which may be useful to someone. It displays all the controls on an ASP.NET Page in a tree structure. You can actually call it from any control, it will recursively traverse the heirarchy below it. I tested it on ASP.NET 2.0, and it works fine:

Call it with the following:

DisplayControlTree(this.Controls, 1, 30);

Incidentally, the problem I had (and still have) comes from dynamically loading User Controls. Once they've been loaded using LoadControl("... path") they don't seem to persist themselves in the ViewState. I think my best hope for now is to save entries made to the User Controls by parsing the Querystring or Form collection manually.


}

Wednesday, November 02, 2005

Buzz Watch: Ruby on Rails

{

Ruby on Rails is getting more and more buzz each time I open my browser. This time it was Bruce Tate claiming that Java is dead ("like COBOL, not Elvis") and that he was turning to Ruby on Rails as his framework for application development.

A few days ago I also noticed a define/tutorial on Ruby on Rails over at O'Reilly. More and more of these seem to be popping up of late.

The most interesting thing about this buzz, however, seems to be the shift in the pendulum swing to a language that is light and airy, one which isn't belabored by the stiffness of strong types.

I remember the process of learning Java - there seemed to be a lot of people coming from a C/C++ background who perpetually scowled at the VB/Microsoft/Webby/Scripter types like me. Now many of this camp are turning away from that rigidity and heading back to the land of "dynamic" typing.

Pendulum swing... a few days ago I met with a prospective client and they showed me an app they were using that was written in PowerBuilder. I don't know much about PowerBuilder but the app seemed quick, flexible, and tightly coupled with the database. What's most ironic is that the reason I was there was to help with stored procedures and triggers that would let them add business logic to the otherwise light and airy environment in which their application came into being.

Deja vu, all over again.

I've got Ruby on Rails on my watch list. Go to the official website and there's even a movie amongst the tutorials.

}

Tuesday, November 01, 2005

Remedial CSS

{

I've been doing web development for a long time. Long enough to have developed lots of patterns and habits for how I'd approach putting together a website. Because most of my work is done with server side code, I've also yielded most layout thinking to the Panels, Grids, and User Controls I create in ASP.NET.

So it's a bit of a surprise now that I find that my habits are wrong, horrid even when it comes to web development. My effortlessly thinking in tables goes against the grain of any CSS ideologies out there. Having just redesigned my personal site, this is a bit of a drag.

As I read up on layouts with CSS, it's funny to see things turned back on themselves:
  • Absolute Positioning - I used to tell everyone to avoid this because of different screen resolutions
  • ul/li tags - Which were so passe, and used as an example of the obscure tags one didn't need anymore.
  • Tables - frown upon for anything other than displaying tabular data. Read: no layouts, thank you.
So I'm beefing up again. I need to learn the particular advantages of these newer layout strategies - after messing around today a bit I don't seem to gain anything over my older methods. I'm sure this will change.

I did some surfing and checked out various sites... most of them are using DIVs and CSS for layout, not tables. Curiously, Yahoo! Picks is one site that seems to have kept things the way they were.

}

Monday, October 31, 2005

Hunting for the elusive column, table, proc, ...

{

One of our clients has a Microsoft SQL Server table with 284 fields. So when I'm given a spec that references the "OrigLoanAmount" field, it's sometimes difficult to ascertain where that field lives. On some systems, especially if you've got familiarity where data are likely to be stored, you can make an educated guess. But if you're interested in some quick digging, try these queries from the Information Schema views:

-- find that elusive column
SELECT * FROM Information_Schema.Columns WHERE Column_Name LIKE '%MyColumn%'

-- list out the tables
SELECT * FROM Information_Schema.Tables

For procedures, views, and functions, I've just queried sysobjects. I learned this from a guy who was in my class once; I used to be one of the hapless Enterprise Manager users until I saw him digging effortlessly with queries like:

-- show me all stored procedures
SELECT * FROM syobjects WHERE type = 'p' AND name NOT LIKE 'dt%'

-- show me all views
SELECT * FROM sysobjects WHERE type='v'

-- show me all user defined functions
SELECT * FROM sysobjects WHERE type='FN'

... and so on.

}

Web Developer Tools

{

Glad I found about Chris Pederick's Web Developer Extension. It's a set of tools that will run inside Firefox or Mozilla revealing the underlying structure of any site you pull up in your browser.

Some of my favorite things:
  • Displaying borders on table structure
  • Displaying borders on frame and iframe elements
  • Showing dimmensions of images on screen
  • Adding your own user stylesheet
  • Displaying stylesheets for a site within your browser

Now to find an IE version...


}

Sunday, October 30, 2005

Office Interop with .NET

{

Are you still doing VBA with Office even though you know you should be doing your coding with the .NET Framework? Probably like many I did things the old way rather than dealing with COM Interop, especially since this was particularly daunting with Office.

It isn't as of a while ago, but you, like me, may have been a bit too busy to notice.

First, you must download the Office Interop Libraries from here. The instructions are clear; run the register.bat from the VS.NET command prompt. After that you can make a reference to the application interop assembly of your choice, such as Microsoft.Office.Interop.Excel.dll.

Reference the namespace in your app:
using Excel = Microsoft.Office.Interop.Excel;


Code away:

Excel.Application app = new Excel.Application();
Excel.Workbook book = app.Workbooks.Open(@"c:\data\Daita.xls",Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets[1];
for(int i=1;i<10;i++) j="1;j<7;j++)" rg =" (Excel.Range)sheet.Cells[i,j];">

A few interesting things:
  • The Type.Missing passed for all those COM-esque optional parameters. Ugh.
  • Casting the cell you are on into a Excel.Range when you need to access its contents.

Finally:
Many more articles can be found
here, on MSDN.

}

Saturday, October 29, 2005

Try. Fail. Try again. Fail better...

{

After months of neglect, I'm going to try this again. No more epics, just short snippets of developer talk.

}

Thursday, June 16, 2005

XML .NET (the custom samples)

{

Here are the examples from the last piece of the course when we explored the .NET Framework's implementation of XML related parsers and techniques.

You can download the sample in this zip file which you can extract to its project form to look at the code. Most examples are "methods" implemented off of Module1.vb1.

Read and Write

The BasicReader() method shows an example of parsing an XML document with a XmlReader. Pay attention to the Select… Case expression to see how to filter nodes based on their types.

The ValidReader() method shows an example of a validating parser (XmlValidatingReader). Although this method does the legwork, our ValidationEventHandler, the method ValidError() is responsible for responding to any "events" related to the validation. I stressed the importance of understanding Delegates here, and did a quick example of what I meant which you can download in a different project, vbDel. If you don't mind looking at C#, you can look at some earlier entries I made about how delegates work. One of the best uses of delegates is to make an asynchronous call to any method you've written. Asynchronous delegates are how asynchronous web service calls are implemented.

The fake SAX Parser we wrote is also in the project, in its own file called SAXP.vb. It is not very complete but should give you an idea of how to get the SAX functionality out of the .NET Framework. If you'd ever want to – that's probably a remote possibility.

The WriteXML() method is a very basic example of how you can use the XmlTextWriter to create XML documents. This isn't too interesting, but if you start to combine the XmlTextReader and the XmlTextWriter, you can start to see the power and ease of the .NET APIs. In the second group, we wrote some code that would convert an attribute based document into an element based one. You will find this in a method called AttToElement().

Transforming

The SimpleTransform() method is an example of the simplest form of XSLT Transformations that can be done with the .NET Framework. Another method, called MemoryTransform(), is an example of how transformation can be done and processed in memory to return results in a string format. You will notice the use of the MemoryStream class in this example.

Serialization

We took two different looks at serialization. In the first we looked at how a built in class, the DataSet, has the ability to persist itself in XML format. Our method PersistDataSet() shows an example of this. In order to demonstrate the retrieval of a persisted DataSet, we wrote another method called ReadPersistedDataSet(). Along the way we talked about the Schema options of the WriteXml method of the DataSet. Although it was a barely noticeable blurb, make sure you investigate the XmlDataDocument class. It's a quick way to go from a DataSet to an XML Dom-like object and back again.

Once we'd seen that type of persistence, we looked at conventional serialization, or being able to take any old class and serialize it into some output stream. We wrote the PersistConventional() method to display this functionality with a class called Person, and then we depersisted in a method called DepersistConventional().

This was a good way to start working at understanding web services. I'll make another entry with the web services demos, but really quickly, the last few examples related to XML and .NET:

XML and SQL Server 2000

We looked at ways to retrieve XML data from the database, and I demonstrated the FOR XML clause of an sql statement. After we looked at a few examples, we wrote the GetXMLFromDB() method that would issue a FOR XML query and return results using the XmlReader. Which left us with one other thing on our "to do" list: inserting XML data into SQL Server directly.

In the project you will find a file called OPENXML.sql. This file contains a series of scripts to work through to understand how one can use the OPENXML function in SQL Server 2000 to build a "rowset" view on an XML document. Once this rowset functionality is understood, it's easy to see how it can be combined with Insert/Select statements to insert data. This is demonstrated in the InsertXMLContent() method.

So that was the tour de force. You can download it all in this zipped project. If you have questions, don't hesitate to email me.


}

Wednesday, June 15, 2005

Java Samples

{

Generated during class with South Dakota State employees but hopefully useful to anyone who wanders this way.

[NOTE: My web host doesn't serve the *.java files, so download the zipfile at the end of this post instead. I'll rename with *.txt later.]

We began things with a Hello World program in Hello.java. Soon after we talked about defining classes, the basic building block of any java program. Clerk.java shows an example of a class with fields, methods, getters and setters (accessor methods), and a constructor. Along the way we also learned about overloading, as seen in Calculator.java.

We learned more details about class definitions: Clock.java (check with TestClock.java) and Employee.java are examples of how you can chain constructors. BankAccount.java was used to show the difference between static and instance methods and fields. You can see the BankAccount class tested in Thursday.java. Once we were comfortable with the static keyword, we talked about defining constants, using Constants.java as our example.

We had a chapter that covered arrays, in which we looked at UsingArrays.java. I added an aside about Collection classes in java, which are a more robust alternative to arrays in most cases, and we looked at Swapmeet.java. Even though I got the bubble sort wrong in class, it's fixed in this example with some helper methods, sortMyArray and printArray. We looked at working with Calendars and dates in TestBed.java. I also included a DateDiff.java that shows how to get the functionality of a basic DateDiff command. Like other things, it's ugly in java.

You saw one class from the swing library, the JOptionPane, which was used to talk about getting user input. I also showed you the BufferedReader along with it in Dialoging.java. I would recommend the BufferedReader approach if your application runs from the command line, personally. For most other examples in class, we used EasyConsole.java, which abstracted reading and writing from the console with a few simple methods.

At this point we began to cover inheritance. We looked at a basic inheritance heirarchy in Person.java, InhEmployee.java, and Executive.java. We looked at abstract classes in Shape.java and we briefly looked at interfaces in IPrintable.java.

We closed out with the basics of exception handlers and subclassing exception. The try{..}catch{...}finally{...} is probably best introduced by your material.

Our final two topics were File I/O and parsing XML documents. On the File I/O side, I had two classes: DavidFileReader.java to demonstrate methods of reading from a file stream, and DavidFileWriter.java, to demonstrate writing to a file stream. In terms of XML, I have a class called Xreader.java which should help you get started parsing XML files.

Wow, that was a lot for three days. Even typing it out makes me tired. In regards to the samples, you can download them individually, or you can download a zip archive of the entire set. If you have questions or comments, don't hesitate to email me.


}

Friday, May 13, 2005

iTunes Hacking

{

So I am still coming to terms with how iTunes works, and trying to get the "philosophy" behind its organization system. My understanding is this: iTunes can scour the hard drive, if you allow it, and maintain a nice library of tracks, no matter where on your physical disk they are located. You can then sift through by artist, etc...

In my case I have ~30 GB of music and much of it isn't in mp3 files with ID3 tags - I've got a pot pourri of mixes and a ton of podcasts I've been listening to while I work. It's too much of a pain to manually create a playlist for all the folders or try to find unlabeled music in the library. Maybe it's because of winamp but I'm used to organizing my music physically, and then grabbing tracks out of a directory that I want to play, rather than by "artist" or "genre." For example, I've got the following:

-/Mp3
----/PodCast
--------/ITConversations
--------/KCRW
--------... and so on
----/Albums
--------/Interpol
-------- /Massive Attack
-------- ... and so on
----/Mixes
-------- /Jan2005
--------/Feb2005
-------- /Mar2005
--------... and so on

This scheme works well, but it doesn't seem to mesh with iTunes. So I wrote a little program using the iTunes COM SDK that takes a directory as a parameter and automatically creates a playlist for each folder that contains mp3 or other music files. In my case it worked perfectly (took seconds!) in creating playlists for all my folders and the files they contained. I put in a "Sync" button too, so it can synchronize with changes you make to file structure.




I've uploaded a *.zip along with source (it's written in VB6). I tested it with iTunes 4.7 and it works fine. I'm not sure whether this was unnecessary; perhaps iTunes has an option for doing just this, I don't know. But more deeply, I think, is an attitude, an approach of giving the user an interaction with a piece of software. In the PC world, one spends a lot more time "organizing" things than does on one on a Mac. I've heard and read often that systems should be able to manage themselves but find myself balking at the notion that the system can do as good of a job as I can. I download faster than I listen, so things must be organized, but the content of the audio is the archival attribute, not the date, artist, or genre. How this can be known outside of the user, I'm not sure.

If you do make a modification, or an improvement (many probably could be made), let me know. I'm also unaware of any plug-in architecture for iTunes, otherwise I'd try to just make it a couple of buttons or menu items in the program itself.

}

Wednesday, May 11, 2005

Supporting Each Other, VB6 in Longhorn

{

I posted a bit ago about Microsoft's MVP revolt with regards to supporting VB6. They've responded in kind with VBrun, "Visual Basic 6.0 Resource Center."

The product manager for Visual Basic, Jay Roxe, responded to the petition on his blog and, most importantly, has acknowledged support for VB6 in Longhorn:
"However, I want to highlight to you that Microsoft is still supporting Visual Basic 6 and will continue to for quite some time. In fact, the Visual Basic 6 runtime is slated to ship as a part of Windows Longhorn, which means that it will be covered under Longhorn’s support lifecycle."
I'm an unapologetic lover of VB6, and find myself still using it all the time for helpful utilities. Most recently I wrote a tool using the Apple iTunes COM SDK to sync my physical arrangements of mp3s and folders with the playlists that it created. It's a nifty tool, and I'll post about it soon along with source code.

}

Vasters on SOA

{

A small time ago I admitted that SOA is still a bit elusive to me as this ubiquitous need we were all unaware of having. Multiple marketing machines are in full swing with it, however, and it's hard to separate useful and useless facts, much less fact and fiction.

I found a lengthy article on java.sun.com which should prove to be more technical (and therefore more useful) but meanwhile I'm also beginning to find some other questions similar to my own.

Clemens Vasters writes in his blog:

" When you look at what’s being advertised as “serviced oriented architecture”, you see either the marketing-glorified repackaging of Ethernet, TCP/IP, and LDAP (“Enterprise Service Bus”), or architectural blueprints that looks strikingly similar to things that people have been doing for a long time with DCE, CORBA, J2EE, COM, or mainframe technologies. What’s different now is that it is easier, cheaper and likely more productive to create bridges between systems. "


A Bill Simser responds:

"Indeed at the lower levels of the architecture stack the base concepts of SO have been around as good practices for years. However, we as an industry haven't been applying these base concepts consistently or properly across solutions so it's somewhat academic. If calling them SOA means that people now pay attention to them and somehow feel better about using them, then that's reason enough for me to accept that SOA exists. "


And finally, visiting his blog, I read something that gels the concept a bit more clearly as he speculates on how SAP might have been implemented in a SOA world:

"But what if the architects for SAP had applied SOA from the get-go? The actual architecture would have been defined as several aggregations of financial capabilities (like accounts, money movements, and so on) with appropriate service contracts. It would have also included a collection of capability that would be needed by the finance functions of a typical organization, again with appropriate service contracts. It would have have included some UI capabilities (Web Parts if they were really on the ball) that could consume these services (and indeed other services from different providers) and have the "appearance" of a traditional "application". However, as architects we would recognize that what the user thinks is the "application" is really just a thin facade to the orchestrations of functions they need. An important additional capability is to easily orchestrate other services that are not part of SAP (for example, a service with AMEX to get your credit card statements that can augment expense reports)."


Definitely food for thought, with my own response as follows:

Relating to your speculating about SAP, however, a few things come to mind. First, a different way of thinking when it comes to enterprise applications. You are right when you say that "traditional" thinking lies around task automation rather than loosely coupled "services" that are stitched together by consuming applications (or environments).

But how much of development revolves around loosely coupled services versus automation? Has the nature of the application changed to justify all the force behind service orientation? In one sense I can see it: the elegance of separate, contractual, modular partners, on the other I see architecture astronauts [http://www.joelonsoftware.com/articles/fog0000000018.html] building a massive framework that ultimately doesn't propel us.

All this talk of "contracts" and "services" and so on, and I contrast this with Amazon ECS - making requests for XML formatted data over HTTP: simple, elegant, and effecient.
The journey continues, but it's midnight and tomorrow's coming fast.

}

Tuesday, April 26, 2005

Asynchronous Delegates With C#

{

In my previous article on delegates in C#, I gave the syntactical basics of delegates as well as a very rough idea of how they could be used in a callback scenario. This time I'd like to revisit the concept of delegates but take it a step further and show you how the .NET Framework wraps the ability to make asynchronous calls right into the capabilities of delegates. In short, once an instance of a delegate is obtained, it comes with BeginInvoke(...) and EndInvoke(IAsyncResult) methods that can be used to piece together an asynchronous call.

In my previous example, we used a class called DB that had a method called RunLongQuery to fake the notion of something that takes a long time. However, it's not difficult to write code that chews away CPU and I/O cycles so this time around we'll use a class that really does take some time to do its work:

public class FileMapper{
public string MapHeirarchy(string startPoint, int thresh, bool top){...}
}


Our class, FileMapper, has a method called MapHeirarchy which takes a directory path, a threshold, and a boolean flag as its respective arguments. The overall goal of this method is simple: you pass it a path and it will graphically map out the directory structure. The integer and boolean arguments are there because the method is called recursively. So if I wrote the following code:

FileMapper map = new FileMapper();
map.MapHeirarchy("C:\\CODE", 0, true);


I'd get a list of the folders underneath the code directory returned as a string. It would look like:

Mapping C:\CODE
-PROJA
--PROJASUB
--PROJASUB2
-PROJB
--PROJBSUB
--PROJBSUB2


Not the most exciting thing in the world, but it can take a long time. For example, to map my C:\Program Files directory took 1 minute and 58 seconds on my Thinkpad. If we have methods such as this, which will take some time to run their course, they are good candidates for an asynchronous call. Asynchronous, in this case, means that once the method call is made, our code will continue executing until we check to see that the method has completed. We don't have to write a lick of thread management code in order to get this behavior; it's all built in for us as long as we know how to define a delegate.

The syntactical basics of delegates should be straightforward if you saw the earlier article. We'll add a delegate to the FileMapper class so that we can call the MapHeirarchy method asynchronously:

public class FileMapper{
public delegate string MapAsync(string startPoint, int thresh, bool top);

public string MapHeirarchy(string startPoint, int thresh, bool top){...}
}


The MapAsync delegate matches the return value and arguments of the method we intend to use it for, MapHeirarchy. I like to call delegates "typesafe method pointers" and point out that they are "typesafe" because you can only point to a method that has the same return type and arguments.

In the class where we are leveraging the FileMapper class, we create an anonymous instance of the class to map the MapHeirarchy method of the instance to an instance of the MapAsync delegate. Sounds like a lot, but it's really just a single line of code:

FileMapper.MapAsync mp = new FileMapper.MapAsync(new FileMapper().MapHeirarchy);

In order to make the asynchronous call, rather than invoking the delegate outright like this:

mp("C:\\DIR", 0, true);

we will use the BeginInvoke method of the delegate like this:

IAsyncResult v = mp.BeginInvoke("C:\\Code05", 0, true, null, null);

From left to right, an object which implements the IAsyncResult interface is returned from an asynchronous call. This is, quite simply, the object which we can "ask" about when the method has finished executing and which will allow us to retrieve the results of the method's execution. The mp.BeginInvoke is the call to our delegated method along with the first three arguments which we've seen defined above. The last two arguments, passed as nulls in this instance can be ignored; they must be a part of the call, but we don't have to know what they are just yet.

The IAsyncResult object has an IsCompleted property which holds a boolean flag indicating whether the method has completed. We can write simple code to poll this property until the method has finished its execution:

while(!v.IsCompleted){
Console.WriteLine("Method still executing... ");
}


Under normal circumstances you may take advantage of a loop like this to display or draw an animation that allowed a user to know that processing was taking place. There are many different directions that this could be taken but it suffices to say that at this point the method you've invoked is executing asynchronously and you're free to carry on with whatever code follows it.

To retrieve the result from the method, we must again ask the IAsyncResult object. Our code may look as follows:

if(v.IsCompleted){
string tmp = mp.EndInvoke(v);
Console.Write(tmp);
}


Notice that after the IsCompleted method returns a true value we have the ability to use our delegate and call the EndInvoke method, passing it the IAsyncResult object to get our return value. The implementation is super slick here because the return type of the EndInvoke method is the return type of the original method!

So here we see delegates one step further: the ability to make an asynchronous call with a delegate without having to worry about Threads, Synchs, Timers, or Locks. We also can see a way in which any method has the potential to be made asynchronous, as long as it has an associated delegate to go along with it. Finally, remember that you can define your own delegates for any method. The delegate that allows you to make an asynchronous call does not have to be defined in the same class whose methods you want to call asynchronously.

Download the full code listing here.

Questions? david DOT(.) seruyange AT(@) gmail DOT(.) com

}

Thursday, April 21, 2005

WinForms ComboBox ItemData

{

For the most part, I work with web based applications, in which a combo box works as you would expect. The class System.Web.UI.WebControls.DropDownList has an ListItemsCollection which consists of ListItem types. So you can dump data into it using the ListItem class which accepts, in the constructor, arguments for text/value pairs. Your code would look something like this:

ListItem li = new ListItem("MyText", "MyValue");
MyDropDownList.Items.Add(li);


You can shorten it with an anonymous instance of the ListItem:

MyDropDownList.Items.Add(new ListItem("MyText", "MyValue"));

Hence, a lot of code people write to populate these from a database looks like this:

// code to connect, build command, etc...
SqlDataReader rsData = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while(rsData.Read()){
MyDropDownList.Items.Add(new ListItem(rsData["TextFld"].ToString(), rs["ValueFld"].ToString()));
}
rsData.Close(); // never forget to close

Another way to do the same thing:

//code to connect, build command, etc...
SqlDataReader rsData = cmd.ExecuteReader(CommandBehavior.CloseConnection);
MyDropDownList.DataTextField = "TextFld";
MyDropDownList.DataValueField = "ValueFld";
MyDropDownList.DataSource = rsData;
MyDropDownList.DataBind();
rsData.Close(); // never forget to close

Whichever your fancy, the bottom line is that the DropDownList behaves as you expect it to: some text that displays to the user and an associated value which you can reference programmatically.


In the Windows.Forms namespace, used for so called WinForms applications, the class System.Windows.Forms.ComboBox is the equivalent of the drop down list. However, the collection it uses for its items is different; it only seems to have a single value associated with it. How does one map text/value pairs?

The underlying collection used by the WinForms ComboBox is of type ObjectCollection. Not too surprisingly, this is a collection of objects. You can, therefore, store any type of object as an item in this drop down list. For example, if I was keeping track of customer statuses, I may have the following data in a lookup table:





CUSTOMERSTATUSES
STATUSNAMESTATUSCODE
ACTIVE LOANACT
PAST DUEDEL

I want a drop down with the status name for the user, but in my code I really care about the status code, not the name. The first thing I can do is build an object to reflect these values:

class StatusData{
private string _StatusName;
private string _StatusValue;

public property StatusName{
get{return _StatusName;}
set{_StatusName = value;}
}
public property StatusValue{
get{return _StatusValue;}
set{_StatusValue = value;}
}
}

I want to add these objects to the drop down, but I want the status name to be displayed. This is the purpose of the DisplayMember property of the System.Windows.Forms.ComboBox class. It will allow me to specify a property to utilize for display on an object that it's storing:

MyWinFormsDropDown.DisplayMember = "StatusName";

After I've specified that, I can then store all my Status objects as references in the ObjectCollection of the WinForms drop down list:

// build collection earlier
foreach(StatusData sd in StatusDataFromDB){
MyWinFormsDropDown.Items.Add(sd);
}


Because I've already assigned the DisplayMember property, it knows which member of the hosted object to use to display. So how do I retrieve the value of the object StatusData that I've stored? Easy: cast the selected item from the drop down list, and then get any property that you want (in this case, we'll get the value).

// in an event somewhere
StatusData s = (StatusData)MyWinFormsDropDown.SelectedItem;
string val = s.StatusValue;

Seems like a massive chore, but if you think about it, there are already text/value datastructures that you can use without having to build unique classes for everything you want in a drop down list. For example, the handy System.Collections.DictionaryEntry would suffice. Try this on for size:

DictionaryEntry d = new DictionaryEntry();
d.Key = "TestName";
d.Value = "TestValue";

MyWinFormsDropDown.DisplayMember = "Key";
MyWinFormsDropDown.Items.Add(d);

Now, rather than building your own custom classes, you can use this provided class instead. But, the more thinking you do about it, the more you'll realize that this is a bit more flexible functionality in the System.Windows.Forms.ComboBox than in its System.Web.UI.DropDownList cousin. Being able to reference an object with any number of values based on what is in a combobox is, to use some street vernacular, "sick." (A good thing).

}

Thursday, April 14, 2005

Beginning with delegates in C#

{

Delegates are one of the mind benders of the .NET framework. Not once have I been teaching the concept without feeling a bit of inadequacy at drawing up a clear and concise explanation. Unless a developer has worked with function pointers in C, they are a new concept. I'll start off with the most basic example of delegate usage, after which I'll write some posts with some more novel ways to leverage them.

If I wrote the following line of code, you'd know what I mean:
int x = 3;

We've declared a variable x and it points to the value "3" on the stack.

If I wrote the next line of code, you'd also know what was meant:
Foo f = new Foo();

We've declared a variable "f" and pointed it to an instance of the class "Foo" on the heap.

I'm stating the obvious because if the previous two lines of code are understandable, you already know the very first thing about delegates: a delegate is a type, just like our primitive int or our class "Foo." The next leap that must be made is that a delegate points to a method somewhere in your code.

Let's expand the definition of the class Foo:

class Foo{
public void FooMeth(){ ... }
}


Is it possible to make a reference to the instance method FooMeth() somewhere in code? Absolutely, my good man; that's what the delegate is for. To make a reference to this method, first define a delegate somewhere:

public delegate void MethPointer()

Let's break that down: public - access modifier, accessible anywhere, void - this is a delegate that will point to a method that returns no value, MethPointer - this is the name of our delegate, and finally () - the empty parenthesis mean that the delegate will point to a method with no parameters. Delegates are typesafe method pointers - the typesafe part is what you see in the definition: our delegate can only point to a method with an identical return value and parameter list.

So now that we've defined our delegate, how do we create an instance that points to the instance method FooMeth() as we mentioned previously? FooMeth() is an instance method, which means that we need an instance of the class first:

Foo f = new Foo();

Now we create a reference to the delegate in the following manner:

MethPointer d = new MethPointer(f.FooMeth);

We pass the method to the constructor of the delegate. All the hard work is done. To invoke the delegated method, we simply do the following:

d();

One more thing about syntax and then I'll introduce a first basic usage for delegates. If you got this far and you're doing okay, this is a side note you should be able to figure out on your own. A lot of the time, a delegate is declared as a public variable in a class. Something like the following:

public class MyClass{
public delegate void Del();
}


So the line above when we created a reference to it comes to us often as:

MyClass.Del d = new MyClass.Del(f.FooMeth);

This is just a simple matter of understanding that if we declare something inside a class, we need to use the classname to access it.

Now that we've got the syntax for a basic delegate, how on earth does one use such things?

The example I always like to start with is a "callback": you can call a remote method and pass a reference to a method in your local class. For example, let's say we had a database utility class called DB that had a RunLongQuery method. This method runs a query against our database that sometimes takes 0.0005 seconds, but for large reports it can take 5, 10, sometimes 25 seconds. Whenever the query finishes, you'd like to invoke a method from your application.

So I've got a class MyDatabaseApp which makes a call to RunLongQuery from DB. But we can design RunLongQuery to accept a reference to a method as a parameter by first putting a delegate in DB and then using it as a parameter on the method. Check it out:

public class DB{
public delegate void Done();
public void RunLongQuery(string sql, Done cback){
// code from query
cback(); // invoke the callback method
}
}


Let's also look at the internals of the class MyDatabaseApp:

public class MyDatabaseApp{
public void FinishedQuery(){ ... }

public void MyAppQuery(){
DB.Done d = new DB.Done(this.FinishedQuery);
DB dbhelper = new DB();
dbhelper.RunLongQuery("select... ", d);
}
}


When MyAppQuery calls the RunLongQuery method from the instance of DB, dbhelper, it passes a delegate reference to the FinishedQuery method. This will automatically be invoked when the query is completed - see inside the definition of DB to see how it's being invoked.

You can download a VS.NET 2003 example of the following here (~15kb).

These are the very beginnings of delegates - our example is also quite trivial because it's just a teaser for one of the more seductive asynchronous callback that can be done with delegates. But by this time, you should be aware that delegates are types - they can be referenced by variables and to create an instance of a delegate we need first to define the delegate and then pass a method that meets its requirements (return type and signature).

Questions? david DOT(.) seruyange AT(@) gmail DOT(.) com

}

Tuesday, March 15, 2005

Done, Not Dead

{

Yesterday I found a link to a petition of VB developers, many of whom are MVPs, demanding that Microsoft not abandon the language/tools that served them well for so many years. I thought it was interesting because it went along much of the thread of "why not a better COM?" which I'd started on earlier.

Today I found Appleman's comments on it; it appears that his take is that of Don Box - VB and COM are done not dead.

Which is sort of interesting; there was a lot that could have been done to make classic VB even better and it's as useful now as it ever was (except for fear that it may become unsupported).

What were some of the things that could have been better?
  • An enhanced IDE
  • More advanced controls (better menus, better toolbar, lists, better browser/net controls)
  • New language constructs and datatypes (compound assignment, collection classes, etc)
  • COM cleanup (less reliance on the registry OR better tools for managing it, builtin version management).
There are many other things I could think of but it suffices to say that with a better classic VB we'd no doubt experience less "energy" about WinForms with the .NET framework.

Anyhow, this seems almost passe for the likes of me. On to XAML and whatever else bleeds "new."

The petition has inspired quite a few retorts here, here, and here.

}

Saturday, March 12, 2005

Believe.

{

XUL is good.

}

Microsoft vs Groove

{

Things are astir: Microsoft has bought Groove and with it, acquired Ray Ozzie as CTO. I always liked the idea of Groove; I've been the child of groupware since my alma mater is a huge customer of Centrinity, the maker of FirstClass software.

Biola runs, in large part, through its version of FirstClass which is known as BUBBS (Biola University Bulletin Board System). Everything from homework assignments, class communication, and student carousing starts on BUBBS.

I think the idea of true groupware bundled with Microsoft Office will be a huge boost to its functionality and it's been a long time since Office had as large a change in functionality. Outlook provided some very lightweight groupware features, but nothing on the scale of Groove.

On my last major project I tried very hard to lobby for the use of Groove as a true groupware solution but I can attribute failure to two things. First, Groove wasn't developed enough. Second, groupware implementations are a group effort and can only be mandated by a higher power.

On the first point, there were things that made Groove cumbersome. It was a very fat client and the machines we were running on (as well as our network) were not state of the art. During the installation, forgotten passwords were not retrievable and so entire accounts for which passwords were lost became dead space, totally orphaned. The chat feature was also bloated; a massive pop up would appear at the bottom of the screen rather intrusively - people started to use MSN messenger because although alerts for conversations appeared, there was no massive pop up on screen.

On the second, because there we had a pot pourri of tools and no mandate to unify them, we ended up using all the different tools to differing degrees - some MSN Messenger, some Outlook, some Word/Excel, some web based applications (FogBugz), and Visual SourceSafe. Each tool on its own was a little better than Groove (Messenger is a better chat client, Outlook was a better email client) and so we gravitated towards the specialized hodge podge rather than the unified but more bulky solution.

It's sad because for so much of our work we needed threaded discussions, not endless meetings and emails that were copied to the entire team. We needed a centralized repository for important documents, not migrating file servers and directories like:
\\testserve\Files\Projects\ProjectXYZ\Documentation\Requirementswith 7 different word documents with names like ReqDoc1.doc. We needed file synchronization across multiple machines instead of ugly copy/paste jobs ("XCOPY deployment" if you want to sound sophisticated... ).

Although Groove still had a ways to go when we used it, this will mark an interesting direction for Microsoft. One thing that is fairly obvious is that Groove needs to be webified; a slick little groupware utility from Google could annihilate the prospect of people paying for a Windows based client to collaborate. This isn't new, but Google has a knack at implementing things much better than others for the browser.

And of course Microsoft is buying the mind of Ray Ozzie. He attributes his affinity to groupware to the university experience as well in his now defunct blog:

Many years ago, in the mid 70's at University of Illinois, I was fortunate enough to have been touched by something called PLATO...

As many of us who had spent years immersed in the PLATO environment left and entered the "real world", we were shocked and dismayed to find a world lacking electronic connection. And as I entered the business world, it simply made no sense to me that computers were being used solely for computing and "data processing"; the collaborative online work environment that I'd taken for granted, that I'd used day in and day out, was simply missing in action. Our work lives are all about interpersonal connections, our businesses processes are structured into connections amongst people and systems that must be coordinated. What better use of technology than to help people to connect?

And so, for most of my life since that time, it has been my goal to explore what lies at the intersection between people, organizations, and technology. To attempt to utilize technology - to mold it, to shape it into a form such that it can help organizations to achieve a greater "return on connection" from employee, customer, and partner relationships, and to help individuals to strengthen the bonds between themselves and those with whom they interact - online. Because - empirically - collaborative technology has substantive value, in reducing the cost of coordination, in providing shared awareness across differences in space and time.

The way that I explore is to build products, and to see how they are used. To see what works, and what doesn't. To listen, to interact, to refine. Because cooperative work exists at the intersection between people, organizations, and technology, collaborative systems are truly fascinating: in order to serve people effectively, technologists must, for example, understand social dynamics, social networks, human factors. In order to serve people in the context of organizations effectively, technologists must, for example, understand organizational dynamics, modularitytransaction cost economics. and

The bottom line to "why?" To create real value in a dimension that I passionately believe in.


Sounds like Ray is quite the technologist, poised to make an impact.

}

Tuesday, February 22, 2005

More SOA

{

Microsoft has a new article (you need it!) concerning SOA (Service Oriented Architecture).

Interesting responses on my Joel On Software post:

Service Oriented Architecture is really a tool more focused on enterprise IT. It's for exposing a companies "business logic" through software. It's not really a concept for applying to a stand alone application like fogbugz or Word or whatever.

Service Oriented Architecture is really a tool more focused on enterprise IT. It's for exposing a companies "business logic" through software. It's not really a concept for applying to a stand alone application like fogbugz or Word or whatever.

If you're a company who has a business such as finance, healthcare etc, you have an IT department who has built custom software which contains your business logic. For many reasons you want to expose that business logic in a generic way so that it can be easily consumed:
1) by other pieces of internal software
2) by external software of your clients
3) by partner companies or companies your might merge with
etc...

And it stands as an important question exactly what type of software one is writing then; I agree that in many organizations SOA (I've worked at gigantic places like Intel and Countrywide and they surely have use for it) is important but I find it hard to believe that it would be as ubiquitous... I'm going to take a back seat and start studying the architecture more and comparing it to the work I've already done and seen in the "enterprise."

}

Saturday, February 19, 2005

Sun killed Java (Again)

{

I was flipping through magazines at Barnes and Nobles and found a reference to an old blog post

He basically says that
that Jim Fawcette wrote about Sun and their blunders with Java.Sun created the initiative for C# and the .NET Framework when they sued Microsoft for trying to put extensions in their Java implementation, J++. Otherwise Microsoft was on the path to making Java the de facto standard for development on Windows.

"The Microsoft language team—then under Dennis Gilbert, who negotiated the contract with Sun—was prepared to fully commit to Java as Microsoft's language for development on what was later named .NET. Microsoft would have made Java its main language and competed with IBM and Sun on its framework implementation, according to contacts at Microsoft then and now. Visual Basic would likely have continued, given its installed base, but it would've been marginalized and C# never would've appeared."

Interesting.

I always thought that Sun's major blunder was that they didn't put a full effort behind the development tools/platforms in Java. By doing so they essentially opened the door for Sun, BEA, and all the other companies that produce duplicate facilities for Java, hence fragmenting the market. My thought isn't really original; Cringely alluded to it back in 2001:


"Sun should have maintained its technological lead, but didn't. Why not? Don't they understand that Microsoft is like the Terminator (as depicted in the original film, the really scary one) and will never give up? .NET, whatever that is, is perceived in Redmond as the future of Microsoft, and C# is the heart of .NET. Microsoft will spend whatever it takes, take as many revs as the market requires, for C# to become the dominant programming language in the world. What other high tech company can be described as being willing to behave that way right now? Would Apple, Sun, Oracle, even IBM spend WHATEVER IT TAKES to accomplish ANYTHING?

No, they wouldn't, and that's why they are going to lose, dang it. Microsoft will lie, cheat, steal, or maybe just work very, very hard—whatever it takes. That's the most intimidating realization of all for competitors."


Well, enough beating up on Java. I still think that it was better technology for its time frame. But it wasn't automated, augmented, and unified.

Oh, and if anyone hires me for a J2EE project, who knows, I may change my mind...


}

SOA and Avalon (XAML)

{

I'm on my way to try and understand what Microsoft and others intend with the so called "Service Oriented" software strategy. Last week I read a whitepaper on SOA and Indigo as well as a short article by Charles Petzold on XAML. I probably won't have many responses to my questions here but I posted on Joel On Software about some frustrations.

I guess my question for Microsoft is "why not a better COM?" The .NET Framework was definitely a step in the right direction, but many of the components one got used to in COM are simply unavailable in the Framework. Instead there is "interop" capability which is much heavier and ineffecient for simple things like SQL DMO and Internet Explorer (SHDocView).

I'll link to comments I find interesting related to these posts.

}

Endtroducing. Raîson D'Étre.

{

Hello,

My name is David. I live in Sioux Falls, SD as a recent transplant from southern California. I'm a programmer of sorts. "Of sorts" means that right now I'm between many things...

A long time ago I started
blogging about technical stuff but it soon became obvious that the people who read my blog were my friends, not my technie cohorts. So things evolved into an open letter which has never ended.

I still like to write about programming, computers, and the technical. I also like the idea of maintaining a technical journal of where I've been and what I've struggled to get past as a programmer.

This blog is about my technical life. Hopefully it will be interesting. Perhaps even, it will become useful.

}