Wednesday, April 28, 2004

ListItemWrapper

Here's a little trick that I use all the time. It's simple but handy.


I often find that I want to have a ListBox full of some particular item - to be completely boring, let's say it's a list of Customer objects. We only want to display the customer's name, but it's handy to store the whole Customer object in the ListBox, rather than just the customer's name, because it saves us having to go through the trouble of looking up a Customer based on their name. And of course .NET completely supports this, since you can add any object you want to the ListBox.


If you were to code up a simple implementation of Customer like this one:


public class Customer {
  private string name;
  private int age;

 
public Customer(string name, int age) {
    this.name = name;
    this.age = age;
  }

  public string Name {
    get { return name; }
    set { name = value; }
  }

  public int Age {
    get { return age; }
    set { age = value; }
  }
}


and if you were to then shove a bunch of these into a ListBox, you might be a bit surprised to find the list box displays something like MyNamespace.Customer for every object - hardly what we want.


The reason for this is simple: when confronted with an object, the ListBox displays it by calling ToString on it. And the default implementation of ToString simply returns the name of the type. Not particularly useful in most situations, but what else could they do?


Of course, this is simple to fix if we're the ones that own the Customer object. Simply adding an override of ToString that returns the name would do it. But what if someone else wrote the object and we don't have the source code? Or what if ToString returns something we don't like? I've run into this enough times that I've found the following trick worth including in my standard bag of tricks. I simply write a class that looks like this:


public class ListItemWrapper {
  private string text;
  private object item;

 
public ListItemWrapper(string text, object item) {
    this.text = text;
    this.item = item;
  }

  public string Text {
    get { return text; }
    set { text = value; }
  }

  public object Item {
    get { return item; }
    set { item = value; }
  }

  public override string ToString() {
    return text;
  }

}


Now, when I want to store a Customer in a list, what I do is this instead:


listBox1.Items.Add(new ListItemWrapper(“Craig“, new Customer(“Craig“, 32)));


Which allows me to have any arbitrary text associated with any arbitrary item. Because ToString is overridden to return the text we choose for each object, the ListBox will display what we want it to. And retrieving the item is as simple as casting to ListItemWrapper and then just accessing the Item property.

Friday, April 23, 2004

Announcing FwContrib

If you read this blog regularly, you know that I spend a reasonable amount of my spare time contributing to the FlexWiki project. You also know that although I think it's a cool project, I hate the fact that the source code is hosted at GotDotNet. Well, we're looking at doing something about that, but it's going to take a little longer than we hoped. So in the meantime, I've relocated all the pieces that I have control over to a SourceForge workspace called fwcontrib. This includes:



  1. FlexWikiPad. A tool for writing wikis that live on your hard drive and don't require any web access. Great for organizing information and taking notes - sort of like OneNote, but uses FlexWiki syntax. I use it every single day.

  2. FwSyncA tool for automatically synchronizing a FlexWiki web site with a set of wiki files on your local hard drive. The synergy between this and FlexWikiPad is obvious, but even without FlexWikiPad this is handy if you want to do a bunch of wiki work offline.

  3. FwDocGen. A tool for generating a pile of wiki pages based on the XML comment files the C# compiler emits. Because FlexWiki has the cool ability to email you when pages on the wiki change, we're using this at one of my clients to set up a build process that maintain a wiki of code documentation that will notify you when something changes. This one still needs some work, but even as-is it's still fairly customizable.

  4. FlexWikiEmacsMode. A simple emacs major mode for editing FlexWiki files. Can be used in conjunction with FwSync to work offline.

  5. WikidPad2FlexWiki. A simple tool for converting the XML export of the very nice WikidPad tool to FlexWiki syntax.

Not all of these tools have been packaged for release yet, but they will be soon, and the source code is all there. 


I'm going to be working on the project to make all this stuff better over the coming months. If you have any feedback for me, be sure to log a bug or a feature request!

Wednesday, April 21, 2004

Constructor or Factory

I had an aha moment the other day. It's nothing that lots of people haven't already figured out, but it helped me see things more clearly, so I'm posting it here.


We were doing some design on some classes for the MSDN project I'm working on, and we were debating how to model a piece of content moving through the system. In the system we're working on, a content set (our term for a page and any other associated files or metadata) flows from the content creator, through a publishing pipeline, and into a database. From there, it's rendered out to the MSDN website.


The problem is that, when content is coming into the system, it starts life as a lump of XML. But when the content is being rendered, it starts life as a database record. Further, there are some properties of the content set that are only present at render time, and some that are only present when the content is being loaded into the the database. We were torn whether to have something like this:


public class ContentSetBase { }
public class DbContentSet : ContentSetBase {
  public DbContentSet() { }
}
public class XmlContentSet : ContentSetBase {
  public XmlContentSet() { }
}
public class ContentSetFactory {
  public DbContentSet CreateContentSetFromDatabase(db args) {}
  public XmlContentSet CreateContentSetFromXml(xml args) {}
}


or something like this:


public class ContentSetBase { }
public class DbContentSet : ContentSetBase {
  public DbContentSet(db args) { }
}
public class XmlContentSet : ContentSetBase {
  public XmlContentSet(xml args) { }
}


The debate was interesting. I was all for the second approach, since I didn't like mixing XML and Database goo in the same class - it just feels like bad separation of concerns. But there was that word...Factory...and it seemed like that's what it was, so it sort of made sense.


I'll admit, I'm not even remotely knowledgable about patterns, but the one I do have sort of a clue about is the factory pattern. You see it all over the place, and it's hugely useful. But here's the trick: it doesn't apply here. Why not? Because the calling code already knows what type of object it wants. Our database loading code always creates an XmlContentSet, and our web page code always creates a DbContentSet. The factory would only be really useful if we were doing something like this:


ContentSetBase cs = ContentSetFactory.Create(args);


and we didn't care whether we got back a DbContentSet or an XmlContentSet. In other words, an important part of the factory pattern is that the factory makes the decision about what type of object to create. In the factory above, the caller was making the decision by calling one or the other method.


Now, that's not to say that the code wouldn't have worked either way: it would have. But it makes more sense to me the second way, and realizing that rule is going to help me figure out in the future when a factory is appropriate, and when it isn't. And that's a useful trick to have in my pocket.


Oh, and in case you were wondering, in the end we wound up doing something else entirely, after figuring out a bunch of other constraints. :)

Process Explorer Rocks

I've long since replaced the venerable Task Manager with Process Explorer from SysInternals. It's just better in every way - from the fact that it will show you which process created which other processes to the fact that the column names actually mean something. But today I found out how truly cool it is.


My machine was thrashing on something, the CPU at nearly 100%. When I fired up Process Explorer, I could see that it was the mysterious “System” process. If I'd been using Task Manager, that would have been pretty much all I could tell. But with Process Explorer, I was able to right-click, bring up properties, and see that one particular thread was the offender. Further, I was able to see the call stack for that thread. On top of that, I was able to click a button to pull up details of the device driver that was using the CPU so heavily.


Love it.

"Creating a Vertex Buffer" Direct3D Tutorial Danish Translation Available

Micael Baerens has kindly translated another of my Direct3D tutorials into Danish. You can find “Oprettelse af et VertexBuffer objekt” (Creating a VertexBuffer) here.


Much more of this, and I will be shamed into writing another one in English. :)

Monday, April 19, 2004

Page 23 Meme

Via Ian, I saw this meme doing the rounds of various blogs. It tells you to do this:



Grab the nearest book. Open the book to page 23. Find the fifth sentence. Post the text of the sentence in your journal along with these instructions.


My nearest book was “Clanbook Nosferatu”, which, on page 23, says



That's part of where we got our sinister reputation.