| |

WPF and Silverlight have a daunting learning curve. There's no doubt about it. All we can do is take one bite at a time and, eventually, we'll finish the elephant. I've talked about my approach to today's WPF/Silverlight tooling and a good intro to routed events and commands, but there's so much more. I haven't talked about dependency properties, but that's probably the second concept you'll have to grasp (before events/commands) as you ramp up on the wide world of XAML. I'm going to skip over it, for now, because I've found something else worth noting: how the value of dependency properties are determined. Obviously, if you don't understand the concepts behind dependency properties, you'll need to brush up, first.
Traditionally, determining the value of a property is simple: you get it's value (referred to as "local value" in WPF/Silverlight). That's it. A call to person.FirstName would return the value stored in the private person._firstName field. If it hasn't been set, then the default value of that type would be used. Simple. If we need to inject any custom logic here, we typically start by doing so in the accessor. For instance, if we want to ensure the value cannot be empty, we add a check to the setter. Things can (and will) get more complex, tho. For instance, we might have a need to allow others to add in their own validation. This would traditionally be handled by an event handler with a Person.FirstNameChanged event. For better or worse, this is all custom and has a lot of room for "creativity." WPF seeks to standardize this and adds a bit of a framework around dependency properties to do so. Determining the value of a dependency property is accomplished in a five-step process.
- Get
- Evaluate
- Animate
- Coerce
- Validate
For the most part, these are all pretty simple to understand. The first step is arguably the most complex, in my mind, because getting the base value isn't as simple as the aforementioned person.FirstName example.
1. Get the Base Value
Obviously, you need to know what value you're working with before you can proceed, but with features like templating and property inheritance, what the heck is the value!? In school, you had PEMDAS; in WPF you have... well, something a bit more detailed.
- Local value
- Style triggers
- Template triggers
- Style setters
- Theme style triggers
- Theme style setters
- Property value inheritance
- Default value
I'm not going to dig into each of these. I simply want to mention a few important aspects to keep in mind. First, "local value" refers to any call to DependencyObject.SetValue() (i.e. Height="123" in XAML or code or Canvas.Left="123" in XAML). The only other thing to concern yourself with, if you're a beginner to dependency properties, is the default value. Default values are not necessarily the same as that of the underlying type. For instance, FrameworkElement.Height has a default value of "NaN" (not a number), despite the fact that it's type, double, has a default of 0. Default types for dependency properties are set when the dependency property is registered.
2. Evaluate
If the value from step one derives from System.Windows.Expression, such as data bindings, WPF converts that to a real value. Pretty self-explanatory.
3. Animate
If the dependency property is currently being animated, the value we've retrieved/evaluated is pretty much ignored in favor of the value set by the animation.
4. Coerce
Next is the injection of custom code via the CoerceValueCallback delegate, if one is registered. Being custom code, you're really left to your imagination on what you can and should do here, but one common scenario is to ensure the value is within expected bounds.
5. Validate
Lastly, we inject one last bit of custom code via the ValidateValueCallback delegate, if one is registered. Validation returns a simple true of false, so there's not much you can do if you made it this far with a bad value. If validation fails, an exception is thrown. For this reason, be sure you take advantage of both coercion and validation, if you have a specific domain you're working in.

JetBrains started work on ReSharper 4.5 recently; but, more importantly, they just made nightly builds available online. I've said it before and I'll say it again: this is the best Visual Studio add-in I've seen... and I'm not the only one who thinks so. I'm a huge productivity geek and ReSharper helps feed my addiction to speed... as in quick. JetBrains won't give you drugs. Although, ReSharper may seem like it, when you work on a machine without it. Development without ReSharper is somewhat analogous to drug withdrawals... cold sweats, lots of twitching, and wondering if you'll be able to finish in time. Okay, maybe not, but I do dread life without it.

Every year, there's one underlying theme that seems to be pushed in the technology arena more than anything. This year, I feel like it's the year of the cloud. The last time I did this was five years ago, so I'll have to back-fill a few years, but here are the themes I've noticed over the past 11 years.
- 2008: Year of the Cloud
- 2007: Year of User Experience
- 2006: Year of AJAX/Web 2.0
- 2005: Year of SaaS
- 2004: Year of Offshore Outsourcing
- 2003: Year of the Architect
- 2002: Year of Web Services
- 2001: Year of XML/.NET
- 2000: Year of Enterprise Java
- 1999: Year of Linux
- 1998: Year of the Web
We've been approaching "the year of the cloud" for a while, now. You can actually look back to 1998, when the web started to really catch on. A few years later, as Java started to build momentum and then .NET hit the scenes, which is when XML as a standard communication language started to catch on. Also tied to the .NET release was a huge push for web services. As this was more and more successful, service-oriented architecture (SOA) started to boom. In my mind, that was a big boon to the outsourcing trends, which have seemingly quieted down a bit, but not completely. SOA also led to the software as a service (SaaS) trend, which triggered Microsoft's software plus services (S+S) push, but that was more of a side story. With everything moving to the web, backed by [typically open] services, asynchronous Javascript and XML (AJAX) was the next big push. This was tied to the "Web 2.0" moniker, which I'd argue wasn't quite what Tim Berners-Lee intended. Either way, this led to the big push for better user experiences, which many people confuse with user interface design. The Web 2.0 push also kept the industry on its web focus, which is where we are left today.
It's easy to look back and see how we got here. Trends show that architectural changes typically take two or three years to gain momentum in the community, so we'll probably have a couple of years before the next major architecture peaks. The trend towards distributed computing has grown more and more, but I have a feeling things are going to start coming back a little. We've been pushing out to the web for a lot of reasons; one of which is the rise of the Mac. What we've been losing out on, however, is the power of the desktop. I see the S+S push to continue, but more as an underlying theme than a strong focus. Services will continue to be the foundation, maintaining the importance of cloud computing, but the desktop will be where the processing occurs. I see Silverlight proving a huge success, which will eventually bring .NET to the Mac. This will probably bring Novell and Microsoft a little closer together, with respect to Microsoft's relationship with Mono, but this may simply be a change in focus for Mono. Oh, and when I say, "bring .NET to the Mac," I'm not talking about the scaled-down version in Silverlight. I'm talking about the real deal. I see WPF and Silverlight merging along with the smart client architecture built into .NET today. This will take more than a few years, but it seems to be inevitable. Most likely, by the time all this happens, multi-core will be a way of life, as opposed to the we-should-be-thinking-about-threading thoughts most developers have today. Armed with a strong multi-threaded foundation, which is easy to use, the combined WPF/Silverlight presentation tier will quickly overtake Flash and Air. By this time, we should also start to see more integration into our everyday lives...
Okay, I'm probably getting a little out of hand here. If I go much further, we're going to be on the USS Enterprise, so I'll stop while I'm ahead. I'll just leave it at, it'll be interesting to see what's next. My money's on the power of the desktop, which we've lost over the past 10 years.
Routed events are one of the foundational components of the WPF and Silverlight architecture. If you're not familiar with the concepts behind routed events, check out Brian Noyes' MSDN Magazine article, Understanding Routed Events and Commands in WPF. This is a great start to understanding the architecture, but Brian doesn't tackle creating your own routed events. After seemingly endless searches, I finally whipped out Reflector to get to the bottom of it. It's pretty simple, but it is different.
For this scenario, I have a collection of items and I needed to raise an event when the selected item changes. Pretty basic. There are three components to this: (1) the routed event identifier, (2) accessor, and (3) event raising call. Again, not too far off what we're used to, but it is slightly different.
public static readonly RoutedEvent SelectedIndexChangedEvent = EventManager.RegisterRoutedEvent("SelectedIndexChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl));
public event RoutedEventHandler SelectedIndexChanged
{
add { AddHandler(SelectedIndexChangedEvent, value); }
remove { RemoveHandler(SelectedIndexChangedEvent, value); }
}
This is where I got stuck. I tried the traditional method to raise the event:
protected virtual void OnSelectedIndexChanged(RoutedEventArgs args)
{
if (SelectedIndexChanged != null)
SelectedIndexChanged(this, args);
}
Obviously, we wouldn't be here if this would have worked. Luckily, all we need to do is replace the if block: RaiseEvent(args). I should also mention that, when you initialize the event arguments, you need to specify the routed event it's being triggered for. this is as simple as new RoutedEventArgs(SelectedIndexChangedEvent).
There can (and probably should) be some deeper thinking with respect to the best way to make this call, but I'm not going to cover that here. I have some half-baked ideas about this as well as what hooking up a routed event should look like, but I'll save that for another time.

If you haven't played with either WPF or Silverlight, you first need to understand the tooling we have available: Visual Studio, Blend, and Design. Most people don't consider Expression Design, but I'd argue that it's perhaps the best way to get started, depending on what you're doing. This is probably common sense, but if you haven't played with each of the tools, you may not realize how valuable each is to your end goal.
Any developer will most likely want to start with Visual Studio. Try it. You'll find yourself wondering where to start. If you're an old school web developer, like me, you'll stare at the XML code and wonder what to type and finally fall back on the toolbox. If you're a drag-and-drop type (either Win or Web Forms), you'll probably go directly to the toolbox. In either case, you'll most likely find it useful to tweak both the designer and XML... well, that's not completely true. If you're comfortable with XML, you'll eventually stop using the designer because it's just too much of a pain to deal with in Visual Studio. Visual Studio is the best environment [today] if you want to modify markup or code. Don't choose Visual Studio if you're a drag-and-drop type of developer. No matter what type of developer you are, however, you'll find yourself wondering if there's a better way because it just doesn't "feel" right. This is when you'll begin to wonder about that "Blend" thing you heard about.
If you're proficient in Flash development or claim the "designer" moniker, you'll probably start with Expression Blend. Blend is the best tool to build an interface along with some key interaction details (read: animations). The problem with blend is, there's absolutely no intellisense in XAML, which I find ridiculous. And, just to put salt in the wound, you can't even edit code (C# and VB) files with the tool. This really drives in the fact that the tool is intended for no-code applications. These don't exist. In my experience, Blend will become less and less useful over time. Why? Because you'll start to realize you can't do everything in XAML and will have to move some things to code. This, in conjunction to run-time bindings in XAML will render the Blend design-time experience useless. Visual Studio is the same in this aspect, but it just because apparent that you'll prefer the intellisense, since you'll want to work with the XAML. Unlike Visual Studio, tho, you'll find yourself tweaking the designer more than the XAML. Coding isn't the only thing that will take you out of Blend, tho.
Let's face it, most people start looking at WPF and Silverlight because they want glam. They want beautiful applications with all kinds of frou-frou animations and transitions. This drives me crazy, but I'm not surprised. Choose WPF and/or Silverlight not because it can be pretty, but because it's the next generation user interface technology. This means, if you're building a new Windows application, don't even look at Win Forms. WPF is the way to go. Microsoft hasn't said it, but Win Forms is dead to me. If you have an existing app, I'd recommend you start looking into interop scenarios. Whether you're looking at WPF and/or Silverlight as the next gen platform or not, you're still going to want that glam I mentioned. This is when you should take a look at the often ignored, red-headed step-child of the Expression suite.
Today, Expression Design is a vector graphics editor. Don't expect to switch to Design for raster images (i.e. GIF, JPG, PNG) -- which is what I was hoping to do -- you'll find yourself missing crucial capabilities. I keep Paint.NET on hand for these needs. Design is best used to build creative visual interfaces. I've used it to theorize and bring certain design elements to life. You might do this with windows, buttons, and other framing elements, for instance. I simply find Design to be a better interface for adding glam to my user interface. Note that I'm not referring to animations. Use Blend for animation; use Design for static visual elements, like rotation, embossing, and the like.
To sum it all up, here's what I believe a WPF/Silverlight project should looked like.
- Know the difference between graphic and interaction design. Essentially this is the user interface vs. user experience debate, it's important to know the difference for staffing purposes. There is a difference and it's substantial. Don't assume that a graphic designer can architect an ideal interaction or vice-versa.
- Get a graphic designer. Unless you have an eye for graphic design, you won't be getting the eye candy you're probably looking for. If you have a passion for this, but it isn't your calling (like me), you might be able to get there eventually, but your time is probably better spent elsewhere.
- Get an interaction designer. The fact that we have dialog after dialog and click after click proves how important this one is. I'd argue this is more important than a graphic designer, but I might be biased. The good news is, this can be learned a lot easier than the artistic nature of graphic design. Don't think you can get there without dedication, tho. There are some scientific guidelines, but I have yet to see a good roadmap. It's more about opening your mind and removing yourself and what you might do from the process.
- Design is the graphic designer's scratch pad. Whether you start with wire-frames or set your sights on the real deal, Design is great for slapping something together that will eventually be useful. Tweak and tweak and tweak until you get something that looks right. Then, export to XAML.
- Blend brings your design to life. Now that you have your XAML, you'll probably need to tweak it to make it slightly more human-readable and maintainable as well as do some initial bindings and animations. This is where three worlds collide. Graphic designers will feel awkward in Blend, but will still be able to be relatively production; interaction designers don't really have a tool, so it will depend on where they came from, but Blend is arguably the best place for them to get started; and, developers are typically more code-focused, so Blend will be awkward for them, too. The bottom line is, Blend isn't the perfect tool for anyone, but it does fill a need. Use it to add interactivity to your design.
- Visual Studio gets the job done. When you're ready to make your app do something real, open it in Visual Studio. Arguably the worlds best development environment -- although not without its flaws -- you know why you're here. 'Nuff said.
As a developer who is very comfortable with markup, I've found that this has changed for me over time. I still believe it's a great workflow that supports some moderate back-and-forth -- at least, between Visual Studio and Blend -- but my habits have changed over time. As I've become more and more familiar with XAML, I tend to create visual and interactive effects in Design and Blend, respectively, and then just look at the XAML to figure out how it's done. Occasionally, I'll open my app in Blend, but not too often. This just depends on how big of an effect I'm trying to implement.
The bottom line is, get some experience in all three of these tools. You'll find your own comfort zone. It may include the all-too-bloated and usability-hating Photoshop with a XAML exporter instead of Design or augmenting XAML editing with a light-weight tool like XamlPadX or Kaxaml. No matter what you grow into, know there will be growing pains. WPF and Silverlight have a huge learning curve, but you're buying into the future. The curve is there for a reason, but will hopefully be lessened as the tools improve. I'm also hoping for some major improvements in .NET 4, but I'll try to touch on that later.

Yes, I said "admins," but, unfortunately, this isn't an announcement. I'm simply thinking of a version of Visual Studio built for, well, admins. Specifically, I'm envisioning an environment to build and debug PowerShell scripts and cmdlets. Of course, this is only a hop, skip, and a jump away from PowerShell as an official .NET language. Imagine that, PoSh.NET... or, would someone force it to be P#? Either way, I like the idea. As an official language, that also opens it up to compiled scripts, which would be great for those servers without PowerShell installed. Of course, it's just a matter of time before PowerShell is default and the legacy DOS shell is eventually phased out. As a matter of fact, that's the plan for Windows 7 and Server 2008 R2. I'm not sure about Server Core, tho, since there's still the dependency on .NET.

I can't say we needed a new logo for .NET, but there have been a few nice logos coming out of Redmond lately. Actually, I never really considered the .NET logo to be an official logo. It was simply some text with very basic coloring. Either way, we now have a new logo to enjoy. I have to say I like it more, but I don't know if I can say I "love" it. I do like the fact that they're looking to refresh the "look." This makes me wonder if we'll see a new logo for Visual Studio 2010. The Visual Studio logo is something like 10-12 years old. I don't know exactly, but it's perhaps the oldest logo that hasn't changed. Well, other than Windows. The Windows logo changes with every release, but that change is relatively minor. I don't see that logo drastically changing for a long, long time. Actually, Microsoft is probably more likely to release a new OS than change that logo. Who knows... that'd probably still be called "Windows," even tho the change would be reminiscent of the MacOS 9 to 10 change.



A while ago, when working on my first Silverlight app -- well, "app" might be pushing it -- I wanted to use very specific fonts to achieve a specific look and feel. I didn't put much thought into what was rendered at first, but soon I realized my fonts weren't being used. I ultimately found out that Silverlight is very limited in the built-in fonts you have to choose from. You can only choose from the following:
- Arial
- Comic Sans MS
- Courier New
- Georgia
- Lucida Sans Unicode
- Times New Roman
- Trebuchet
- Verdana
- Wingdings
I was very disappointed when I found out about this because I'm in love with the fonts released with Office 2007, namely Calibri, Cambria, and Consolas. I did say "built-in fonts," however, which is perhaps misleading. The reason for the limited fonts, which I'm sure you can guess, is because Silverlight is aiming to ensure the font you'll need is on the client's machine. What sucks about this is that, even if the client has the font, you still can't use it with a simple name reference, like you can with CSS. There is one work-around, tho.
To use a custom or non-standard font, you simply need to specify a path to the font. The problem with this approach is that it requires the client to download the font file, even if they already have the font locally. I still don't like this, but it's better than no option at all. To specify the font path, you have two options: FontUri property or the <uri>#<font name> syntax within the FontFamily peroperty. This may change in Silverlight 2, but I believe it's consistent with WPF, so I doubt it.
My only hope is that a future version of Silverlight might include a quick check to see if the font is available on the client before downloading it. This should give you the flexibility of using common fonts that aren't considered "standard" to Silverlight without increasing download size significantly across the board.
The last thing I should mention is the use of fall-back fonts. As I understand it, Silverlight support fall-back fonts, but I'm not sure how, unless you're using a custom font. Fall-back fonts in CSS are used when the first font is not available. Since Silverlight limits you to what fonts are theoretically ubiquitous, there doesn't seem to be a need for fall-backs. I can only guess that a fall-back would be used in a case where a font fails to download or the URI is bad.

Someone I work with came to me recently and showed me an interesting bug. In Visual Studio, you can force a project to be built as 32- or 64-bit by going to the project properties Build tab and specifying the target platform. He did this and then proceeded to build the app. This put all the binaries in a \bin\x86 directory. WTF!? I tried it myself and -- not that I doubted him -- I got the same results. The build directory still had the previous value of \bin\Debug, so I found this odd. I changed the build directory to \__bin\Debug and guess what... that's exactly where it went. I thought this was odd, but remembered the IE7 bug on Windows Server 2003 I mentioned a few months back. I changed it back to \bin\Debug and everything worked like a charm.
It looks like changing the target platform changes the build location and, to get around that, change the build directory to something else, save the properties, and change it back. Annoying, but at least you only have to do this once. I went ahead and added this to Connect.
Symptoms
When opening a solution with a web project in Visual Studio, you receive the following error in a popup dialog:
System.Runtime.InteropServices.COMException
Cause
Apparently, this is an issue with IIS configuration. I'm not quite sure why we get such a useless error message, tho. Very annoying. If you're not sure you're seeing this with a web project, load the solution and, when the error pops up, look at the status bar. You should see a "loading" message with the path of the problematic solution.
Resolution
- Ignore the errors and let the solution load
- In the Solution Explorer, right-click on the project that failed to load, click Edit <project file>
- Scroll down to the bottom of the file and look for <UseIIS>True</UseIIS> (located at \Project\ProjectExtensions\VisualStudio\FlavorProperties\WebProjectProperties\UseIIS)
- Repace True with False
- Save and close the project file
- In the Solution Explorer, right-click on the project, click Reload Project
More Information
- Applies to: Visual Studio 2005, 2008
|
|
|
|