April 28, 2007
It took me a long time to learn how to think in WPF. I had spent years plunging into the depths of Windows Forms, and before that I learned the ropes of MFC. Since WPF is a complete departure from the world of the HWND, most of my knowledge and “second instincts” gained from working with those other platforms had to be unlearned. That’s not easy to do.
I realized the other day that my thinking about WPF has changed dramatically over the past five or six months. Some of my older blog posts solve problems in ways that now seem to be “swimming upstream” to me. Back then I was trying to solve WPF problems by applying a WinForms way of thinking. I feel that now I have found the “spirit of WPF”, so to speak.
Below is a list of ten tips which, I feel, capture the essence of thinking in WPF. This list is by no means complete or “correct.” The tips are rules of thumb, not hard and fast absolutes. Take these ideas with a grain of salt; perhaps your way of approaching WPF is completely different than mine.
- Do not hesitate to write code. Just because you can do so many things with XAML does not mean that you should. WPF is an application development platform. Applications are written in code, and use markup when appropriate.
- Keep your XAML dumb. Avoid being the geek who spends an hour concocting a dozen lines of abstruse XAML to do something which could easily be done with one or two lines of code. XAML is great for declaring objects and the relationships between them. It is possible to express behavior in XAML somewhat, but think twice before doing so. Eventually your functional requirements might become more complicated, and you might find yourself rewriting that XAML logic in code anyways. Always remember, there is no XAML debugger (except for your brain) and you cannot handle exceptions in XAML!
- Keep visual resources out of value converters. You should avoid referencing brushes, images, colors, etc. in your value converter code. Keep that stuff in XAML. For instance, do not create a value converter which returns a brush. Instead, create a value converter which returns a value that a trigger can use to select the appropriate brush. Doing so makes the value converter more reusable, and allows you to keep brush declarations in the XAML file, where they belong.
- Create modular value converters. Avoid creating value converters which will only be used once. It is better to build up a library of simple, modular value converters, which can be combined using the ValueConverterGroup.
- Expose functionality as services, not subclasses. Many features of WPF are exposed as services. A service can be enabled for a particular element/control by setting an attached property on it. Examples of this include validation, spellchecking, scrolling, drag-and-drop, and more. It is preferable to expose extra functionality through one or more attached properties, as opposed to creating subclasses, so that the behavior can be used or not used with ease. The consumer of that functionality will appreciate not having to change the type of element in his/her UI just to make use of it. Also keep in mind that this “service oriented” approach is not always desirable or technically feasible. It’s just a rule of thumb.
- Think thrice before creating a custom control. It is rarely necessary to create a custom control in WPF. Before you go ahead and subclass Control, consider your options. Read this great article for an overview of what those options are: http://msdn.microsoft.com/msdnmag/issues/07/05/WPF/default.aspx
- Do not micromanage, let panels do the work. One of the best parts about WPF, in my opinion, is the layout system. You put visual elements in a panel, and the panel manages the location and/or size of those elements for you. You can put elements in a Canvas panel if you want to specify absolute coordinates for them, but you normally should not be doing so. If you find that you are specifying coordinates for elements a lot, consider using other kinds of panels to make your life easier (and UIs better).
- Carefully consider where to put resources. The resource system in WPF is brilliant, if used properly. When designing an application be sure to keep the hierarchical nature of resource lookups in mind so that you avoid duplicating brushes, images, data sources, etc. Get into the habit of creating separate resource dictionaries for logically distinct resources. You can use the MergedDictionaries property of ResourceDictionary to import physically separate resources at runtime.
- Strive for elegance, not eye candy. With all of the visual goodies at your disposal it is tempting to add superfluous crap into a user interface. Avoid this temptation. If you find yourself adding animations that do not enhance the usability of a user interface, remove them. Above all, keep it consistent. When you find a visual style which is appropriate for your application, create Styles that can be used to promote that look and feel throughout the application. You don’t want your UI to look like a ransom note!
- Avoid being a Blender. I am starting to see a lot of people who tinker with the Expression Blend program and suddenly call themselves WPF developers. Blend is a nice comfy way to get familiar with many of the basics of WPF, but it is not a good way to really learn WPF. If you want to really understand the platform, write your XAML by hand. Look at the WPF assemblies in Reflector. Subclass some WPF classes and see what it takes to customize their behavior. Frequent the WPF Forum. Read the documentation! Those are the things that will truly show you how vast and incredible the platform is, not fiddling around in Blend. In my opinion, Blend should be used as a productivity enhancer for people who already know WPF.
April 28, 2007
I recently posted another WPF article to CodeProject. It is a revamped version of an old blog post. The article shows how to conditionally highlight ListViewItems, based on values in a DataTable. This article is quite different from the original blog post. My original approach went against the grain, the new approach flows with the way that WPF should be used.
Here’s a link to the article: http://www.codeproject.com/useritems/HiliteListViewItemsInWPF.asp
April 25, 2007
“Josh Smith on WPF” has gone retro! That’s right folks, it’s time to dust off those bellbottoms and bust out the afro pick. Well, perhaps I should explain…
The old version of this blog bit the dust. I received word from the IT Admin at Infusion that the “Josh Smith on WPF”, which they hosted, was deleted. All of the content was zapped, for reasons I’ll probably never know. That really stinks, but such is life.
The good news is that I’ve actually had loyal readers here for quite some time. Two of them, Rob Zelt and Nishant Sivakumar, had backup copies of my old blog. I now have a considerable amount of my old blog entries, and intend on reposting them either on this blog or as articles on CodeProject.
To that end, I just polished and posted one of my favorite old blog entries on CodeProject. This one discusses how to use the ItemsPanel on a ListBox to customize the way that its items are arranged. For those of you who have been reading my blog for a while now, you might remember this as the post with all of the pictures of toy robots.
Here’s the link, in case you’re interested: http://www.codeproject.com/useritems/CustomListBoxLayoutInWPF.asp
April 20, 2007
I have been whining and moaning about the lack of a DataGridView replacement in WPF for a while. During that time, Infragistics and Xceed have been busy filling that gap, so I can’t clamor on about it any more. Soon I will be publishing some posts about the grids, what features they have, how they can be customized, etc. I think that is an important body of knowledge to bring to the table.
On a tangent, word on The Grapevine is that if you have a subscription to Infragistics’s NetAdvantage suite on April 22nd, you will automatically get their WPF control suite for free. If that’s true, then it’s a pretty sweet deal for those of us with NetAdvantage subscriptions! I suppose they have that deal set up to encourage folks to renew their subscriptions, and it will probably work considering the payback!
Soon you can expect to start seeing some info here on my blog about the all-important WPF data grids. Until then, try to ignore the drum roll.
April 20, 2007
I have some bad news for the WPF community. :(
I discovered today that my old “Josh Smith on WPF” blog no longer exists. That blog was hosted by my previous employer, Infusion Development, but suddenly just dropped off the Web. At first I thought that maybe they tear down the blogs of employees that leave the firm. But I looked into it and that is not the case. For some reason, only my old blog has disappeared.
This really stinks because all of that content on my old blog is no longer available. It’s gone. There was a lot of useful information on that blog. I think that I might have back-ups of some of the old posts somewhere. Hopefully I can dig them up and repost them.
I’ve sent some e-mails to people at Infusion, asking what happened to the old blog. So far, nobody knows. Hopefully this is just a temporary glitch and the blog will be revived sometime soon. If the content still exists but they don’t want to host it anymore, I’ll bite the bullet and post the old content on my new blog…if they are willing to send me the files.
The lesson I learned from all of this is that you should never start a blog on your employer’s blog site, unless you intend on never leaving (or you’re employed by WordPress!).
April 16, 2007
So the codename “WPF/E” has gone the way of Elvis (no, it’s not working at a 7-11 in Florida). Now WPF/E is called Silverlight.
Silverlight?! What the Hell? What a stupid name. ‘Silverlight’ sounds like the name of a surfboard company!
There’s something amiss when a codename is much, much better than the “real” name given to a technology. At least ‘Windows Presentation Foundation Everywhere’ conveyed meaning! ‘Silverlight’ conveys squat.
Come on, Microsoft! What’s up with this naming madness recently? Put away the bong. First you rename “WinFx” to the completely misleading “.NET 3.0″ (biggest mistake of’em all)…then you insist that the first version of WPF be “v3″ since it was released with .NET 3.0…now you call WPF/E “Silverlight”? This is almost embarrasing for your developer communities.
April 13, 2007
The Binding class in WPF has some interesting behavior of which you should be aware. By default, when it encounters a DataSourceProvider subclass it does some fancy footwork which makes most use cases intuitive, but can throw a monkey wrench into other scenarios. I am referring specifically to the BindsDirectlyToSource property. By default that property is false, but sometimes you will need to set it to true. Here’s an example…
Someone recently posted a question on the WPF Forum which asked how to bind the visibility of a Grid panel to the ObjectInstance property of an ObjectDataProvider. Basically, he wanted to hide a Grid when the ObjectInstance property was null, and show it when the property was non-null. The ObjectDataProvider’s ObjectInstance property was set to a non-null value when the user created a new document in his application. In addition, he wanted to do all of this in XAML.
It turns out that this is one of the rare scenarios where you actually want to bind against a property of ObjectDataProvider, not the data object it exposes via the Data property. Here’s a summary of the XAML I created to solve this problem:
When you run the demo application, it will initially look like this:
When you uncheck the CheckBox, which gives a value to the ObjectDataProvider’s ObjectInstance property, it will look like this:
That’s right Buckwheat, an object exists.
(Note: This example is not a scenario in which binding directly to the ObjectDataProvider is absolutely necessary. You could just bind to the provider without setting BindsDirectlyToSource to true or setting the Path to ObjectInstance property, and get the same results. The point here is that if you want to bind to a property on the data provider, you need to bind directly to the provider itself.)
You can download the source code here: BindsDirectlyToSource demo app Be sure to change the file’s extension from .DOC to .ZIP and then decompress it.
April 12, 2007
I stayed home from work today with a nasty head cold, and ended up laying on my couch for hours with nothing to do. Since I had already written 90% of the fifth article in my Guided Tour of WPF series, I decided to finish it up, in between naps and sneezes. This article is about styles and how they are used in my absurdly stupid WPF Horse Race demo app. You can read it here: http://www.codeproject.com/useritems/GuidedTourWPF_5.asp
April 11, 2007
A new author on CodeProject, Dmitrij Zaharov, posted a good introductory article about adorners in WPF, read it here: http://www.codeproject.com/WPF/AdornersWPF.asp It’s a nice intro to the topic, if you’re not a WPF newbie. A few more screenshots would have been nice, but the article is accompanied by four demo projects…so that makes up for it.
On a side note, I’ve started writing the next article in my Guided Tour of WPF series. The next one is about styles, so I need to bust out my Gucci thingamabob before writing it…