Mad Props!

Omniscience is just a Google-search away.

Login

You're reading Mabsterama, the weblog of Matt Hamilton. Enjoy your stay.

NEWStopia

Last night was the first episode of Shaun Micallef's new satirical news show, NEWStopia. Shaun is a genius when it comes to bizarre comedy (especially playing with language), so there's a lot more of that than you'd find on, say, something by The Chaser.

All in all I was pretty happy with it. A few laugh out loud moments.

The best part is that you can watch it online for the next week at their official site! I'm not sure how it will play out with my readers from overseas (there are a few Australian political references), but I'd like to find out! Give it a look and let me know!

Add Logic to Interfaces using Extension Methods

Ok, a little back story for this one:

I have a class called "Farm" defined in an assembly. It's a business class, if you will, that represents a farm in our company.

In the same assembly I have an interface that I call "IFarmsProvider". It defines all the things that you can do with farms. Methods like "GetFarmsBySite" and "SaveFarm".

Obviously my IFarmsProvider interface doesn't contain any logic - interfaces aren't allowed to. All it does is tells me what methods I need to implement when I start defining (in a new assembly) the implementing provider class for farms. For example, a FarmsSqlProvider class which knows how to get farms from a SQL Server database.

The Farm class has an "ID" parameter (a nullable int) which really should be read-only to the outside world. After all - once you've retrieved a farm from the database, it makes no sense to change its ID: That's the thing that the provider will use to match that object up with its in-database counterpart when saving.

So that's fine - I can make Farm.ID a read-only property and add a constructor that accepts an integer. Now I can construct Farm objects straight out of the database. If the user creates a Farm using the default (parameterless) constructor, then the ID is null and the provider knows that this is a new farm that needs to be created in the database when it's saved.

Here's the rub: When I add new farms to the database, I want to set that farm's ID to the new farm row's ID. It's an identity int in SQL Server so it gets the next available value. But ... Farm.ID is read-only! How the heck am I supposed to change it?

Right now we've taken the easy way out and made Farm.ID a read/write property. It lets us set the ID in the providers we implement, and we just have to hope that other developers don't go changing the value before they save existing farms. Not ideal.

So today I played a bit in beta 2 of Visual Studio 2008, and tried something out.

First, I redefined Farm.ID like this:

 public int ID { get; internal set; } 

So only classes within the assembly can set the ID of a farm.

Next, I defined a little extension method for my IFarmsProvider interface, like this:

 public static class FarmsProviderExtensions
{
public static void SetFarmID(this IFarmsProvider provider, Farm farm, int id)
{
farm.ID = id;
}
}

Now any class that implements IFarmsProvider has a method called SetFarmID! That method has access to the internal setter on the Farm.ID property!

Strictly speaking, this doesn't stop other developers from calling the SetFarmID property if they really want to change an existing farm's ID. However, it does stop them from absent-mindedly typing "myFarm.ID = 3" somewhere in the middle of a method, since Farm.ID is not settable from outside its assembly.

Extension methods in .NET 3.5 are a great way to add "logic" to interfaces. It's almost like having multiple inheritance! Boo ya!

The Five Feed Groups

"Feed Groups?" I hear you ask! "Don't you mean food groups?"

Well, no. I'm talking about the Five major Feed Groups! A way to categorize the RSS feeds you subscribe to, in order of how they impact on the health of your skills.

 Feed Pyramid

Fruits and Vegetables

The group we need the most of, and in my case it's all about technical blogs. Blogs that really cut to the chase and give me solutions to problems, code samples, walkthroughs ... all the good stuff. Some examples:

Sahil Malik's blah!bLaH!BLOG!!

Sahil blogs about just about every .NET-related technology you can name, and his posts consist of great technical information. He digs deep.

Eric Lippert's Fabulous Adventures in Coding

Eric posts some real gems around C# debugging and gotchas, as well as some interesting stuff like his recent series on the A* path finding algorithm.

Scott Hanselman's Computer Zen

For posting a well-rounded blog that has all the intellectual nutrients you need in one place, Scott's blog is the avocado of the blogging world.

Meat, Eggs and Nuts

Complimentary to the fruits and veges group is the meat group, and here we find the feeds that aren't so much about code, as coding. They're philosophical blogs that post about ideas in the industry and opinions on technology.

Joel Spolsky's Joel on Software

Joel is a staple of the blogging community, and posts insightful articles about the design of software and the development process.

Leon Bambrick's secretGeek

Fellow Aussie blogger Leon Bambrick has a very entertaining blog, and more often than not it really stimulates the thought process. He had (has?) a great series on starting a "Micro-ISV" which is a must-read if you're an aspiring software developer/salesman.

Jeff Atwood's Coding Horror

If you're not reading Coding Horror already, go and subscribe now. I'll wait. Heck, go back and read the entire archive. I'll wait for that too. It might take you a few days, but it'll be worth your time. Jeff is the scotch fillet steak of the meat blogging group.

Bread, Cereal, Rice and Pasta

The bread group for me represents all the blogs run by product development teams. You can't get any more insight into a product than by reading technical posts from the people behind the curtain.

Jensen Harris' Office UI Blog

Jensen made a long series of posts about the new user interface for Office 2007, and it was an incredible read. His blog has been quiet for a while, but I suspect it'll pick back up as Office 14 kicks into gear.

The Windows Presentation Foundation SDK

The WPF team has a great blog with technical posts around their technology. Definitely worth reading if you're developing in WPF at all.

Rick Brewster's Paint.NET

Paint.NET is one of the most awesome pieces of freeware available, and Rick's blog is chock full of fascinating technical posts as well as insights into the world of freeware development. Rick's blog is the crusty dinner roll of the cereal group.

Milk, Yoghurt and Cheese

The dairy group consists of the news feeds that you keep an eye on to keep up to date in your field. You may not need to pay close attention, but it's nice to see what's new every once in a while. Feeds like:

Channel9

Microsoft's Channel9 is not so much news-oriented, but it posts some great video interviews and audio shows that give you a peek inside the MS machine.

Paul Thurrott's SuperSite for Windows

Paul has run his site for quite some time, and it seems to get bigger all the time, with new categories of posts and reviews. It's not just Microsoft-oriented, either.

LiveSide

LiveSide is a site run by enthusiastic watchers of Microsoft's online services, and they post some really great stuff about upcoming MS products or developments therein. They get some real scoops over there. See also Long Zheng's istartedsomething. LiveSide is the baked cheesecake yoghurt of the dairy group!

Fats, Oils and Sweets

Our last group, the sugary sweet group, is the group of feeds you subscribe to to keep yourself entertained. Perhaps even to keep yourself sane. It's the blogs of your friends, or the Xbox news blogs, or the humour blogs. I won't bother listing mine here, since this group is all about your own personal preferences.

So there you have it! The Five Feed Groups! Make sure you get a bit of each in moderation to keep your brain healthy!

Use Opacity for Secondary Text

In the project I'm working on right now, I have a ListBox that shows the "important" text for each item, and beneath it a description that's less important. Here's a screenshot to illustrate:

ListBox with Primary and Secondary Item Text

The way I originally did this was by simply setting the "Foreground" property on the second TextBlock to "{x:Static SystemColors.GrayTextBrush}", making it appear "disabled" - ie gray.

The problem with that is that when an item is selected, the gray text is very difficult to read against the blue highlight colour. If the user has selected gray as their highlight colour (that is, they've customized their Windows theme) then the text would be nigh unreadable.

The solution? Well, originally I had used a DataTrigger to determine if the hosting ListBoxItem was selected, and setting the colour to something else if so. This was ugly, though, and difficult to get right if you wanted to take different highlight colours (ie not just blue) into account.

So now I'm using the Opacity property of TextBlock rather than its foreground colour. Setting the Opacity to "0.5" makes it 50% transparent. That way it renders as gray when it has a white background, and as light blue when selected. Here's the same screenshot with an item selected to show what I mean:

ListBox with Selected Item

Looks great! So try the Opacity property on TextBlocks for this sort of "secondary" text.

My Blog Heartbeat

Scott Hanselman has started a meme, and I can't resist a meme. Particularly one that involves SQL queries and Paint.NET.

So here is my blog posting frequency per month (click to enlarge):

Blog Frequency

As you can see, I started off pretty shaky, hit a great patch in mid 2005 (when I first discovered .NET 2.0), and have stayed pretty consistent for the past year or so.

And here is my blog heartbeat:

Blog Heartbeat

Nowhere near Scott's count, but I'm pretty happy with that.

Xbox Fears

My Xbox 360 is starting to make me nervous.

More and more frequently it's freezing up on me. Generally as I exit an Xbox Live Arcade game (eg Catan), or as I try to launch one. Once it freezes I have no option but to turn it off and back on again.

A bit of browsing on the Xbox forums reveals that intermittent freezing is a sign that your console is headed towards the dreaded Red Ring of Death. Something that Euan has already experienced.

In a way, I kind of hope that it happens sooner rather than later. Just get it over with so I can send it away to get repaired. Microsoft seem to have a permanent solution to the problem nowadays - otherwise they wouldn't have extended the warranty for all consoles out to three years.

I know all of you are on the edge of your seat about my Xbox, so I will keep you posted.

Tafiti vs Live Search

A few weeks ago, Microsoft released a nice little Silverlight-based web search site called Tafiti.

Everyone who links to Tafiti says that it's based on Live Search. However, check out the search results in Tafiti if you search for "comicster". The actual Comicster home page is nowhere to be seen.

Searching for "comicster" on the Live Search site yields much better results - the main Comicster site is the first result.

So if Tafiti is based on Live Search then the developers have done something wrong. The UI is very neat, but the search is pretty bad. I'll stick with Google for now. Sorry guys!

Pete's Latest XNA Project

As a test of posting videos to Mabsterama, here's the latest XNA project from Pete over at BrownBot. It's a kaleidoscope-style plasma tunnel effect, running on his Xbox 360.

RoleProvider - RoleTypeDescriptionProvider

Here's the last step in creating our RoleProvider class, which surfaces custom properties for roles you define so that WinForms and WPF can bind to it.

We've already defined a PropertyDescriptor to represent the boolean 'role' properties, and a CustomTypeDescriptor which tells the framework that these new properties exist. Now we need to tie that back to the original class, so that the RoleProvider class uses this new CustomTypeDescriptor to describe itself.

We do that with a TypeDescriptionProvider. Here's the code:

internal class RoleTypeDescriptionProvider : TypeDescriptionProvider { public RoleTypeDescriptionProvider() : this(TypeDescriptor.GetProvider(typeof(RoleProvider))) { } public RoleTypeDescriptionProvider(TypeDescriptionProvider parent) : base(parent) { } public override ICustomTypeDescriptor GetTypeDescriptor( Type objectType, object instance) { ICustomTypeDescriptor td = base.GetTypeDescriptor(objectType, instance); return new RoleCustomTypeDescriptor(td, instance); } }

We use this by adding an attribute to the top of our original class, like so:

 [TypeDescriptionProvider(typeof(RoleTypeDescriptionProvider))] public class RoleProvider 

And oila! Our class now has as many custom properties as we like, based on the roles we add to its "Roles" property!

Many thanks to the MSDN Managed Newsgroup Support Team for this blog post, which taught me how to do all this stuff, and to the commenters on that post who cleared up a few "gotchas" along the way.

RoleProvider - RoleCustomTypeDescriptor

In the last post about our RoleProvider I outlined the RolePropertyDescriptor, which is a class that describes the custom properties our class will have (representing the roles a user might belong to).

This post is about the RoleCustomTypeDescriptor, which is the class that tells the framework which "role properties" belong to the instance of RoleProvider it's looking at.

So if you have instantiated a RoleProvider and added a role to it called "DepartmentManagers", you want the binding framework to see a "DepartmentManagers" property on that object, of type "bool".

And here's the code!

public class RoleCustomTypeDescriptor : CustomTypeDescriptor { public RoleCustomTypeDescriptor(ICustomTypeDescriptor parent, object instance) : base(parent) { _instance = instance as RoleProvider; } private RoleProvider _instance; public override PropertyDescriptorCollection GetProperties() { return GetProperties(null); } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { PropertyDescriptorCollection props = base.GetProperties(attributes); List<PropertyDescriptor> allProperties = new List<PropertyDescriptor>(); foreach (PropertyDescriptor prop in props) { allProperties.Add(prop); } foreach (string key in _instance.Roles.Keys) { PropertyDescriptor kpd = new RolePropertyDescriptor(key); allProperties.Add(kpd); } return new PropertyDescriptorCollection(allProperties.ToArray()); } } 

So our custom type descriptor takes the instance in question as part of its constructor, and caches it away in its "_instance" private field. It then overrides the "GetProperties" methods, and it's in there that we add a new property for each defined role to that particular instance of the class.

You'll notice that I've overrided both versions of GetProperties. This is the trick to making this work in both Windows Forms and WPF. WinForms' data binding engine looks for the version of GetProperties that takes an "attributes" parameter. WPF's looks for the version that takes no parameters. You need to override both if you want this class to work in both frameworks.