I believe very strongly in using the Model-View-ViewModel (be sure to search the blog site and read all the related articles) design pattern when programming in WPF. You want your UI to be as "dumb" as possible. There’s two reasons for this. First, we’re moving towards a world where designers will be creating our UIs, so you need to find ways to remove the programming from the UI design entirely. The designer should be able to use Blend or some other design tool to first mock-up the layout, and then databind the UI to objects provided by the programmer. If you put logic in the UI directly, it complicates the process for the designer. Even the idea of letting the developer modify the codebehind after the view has been mocked up isn’t enough, since this still makes it difficult for the designer to make large changes to the UI later (such as replacing a ListBox with a Combobox or other such design changes). Databinding and Commands actually allow the designer to tie controls to data and actions with no regard to the logic involved.
The other reason is for testing. Testing UIs is non-trivial at best. UI test automation software relies on simulating a user via "robot" scripts. If you’ve ever done this, you know that writing these scripts is non-trivial. Worse, they break with every minor UI change. This makes doing automated UI testing extremely difficult at best. However, by not putting real program logic in the UI code at all, it makes testing the full functionality of your application as easy as testing can be. A little human testing of the actual UI will then suffice.
So, after that long diatribe, let’s get to the heart of what I wanted to blog about. I’ve been working on that MtG Binder application, and actually have an application running now that does everything that Gatherer does. Lots of design work needs to be done on it yet, since the current UI is functional but not pretty. There’s also a lot of features that go beyond Gatherer that I plan to add. In other words, lots of work yet to do. But I’ve learned a lot about WPF development by undertaking this endeavor.
One of the things I strived to do with this application is to use the M-V-VM pattern. That’s a good thing, since it allowed me to hack together a working "prototype" that’s "functional but not pretty", while allowing me to easily turn it into something "elegant" with out having to touch the code. The key to this pattern, to my mind, is the VM. Anyone who’s done UI work before is familiar with MVC and it’s variants, such as Document-View from MFC. So there’s nothing to learn about proper data modeling, and not much to learn about proper view construction. What’s new with WPF (and yes, I know it’s not new to Mac developers and other folks) is how databinding and Commands allow you to really put all of the user interaction logic inside the ViewModel instead of in your View. Even if you consider the ViewModel to just be the Controller from MVC (I don’t think that’s accurate, but you can make the argument), with older technologies you still had to put a lot of logic in the View. Not anymore. Data, data conversions, data manipulations, and basically anything involving data can now be put into a ViewModel and trivially bound to UI controls. This means complex control interactions, such as changing data displays in a panel based on the item selected in a listbox no longer needs any event logic at all. For more complex user interactions, you can use Commands to abstract away the action coupling from the actual action. A Command that submits data can be bound to the action taken from clicking a button, or to the action of losing focus on a control, all with no event handling logic needing to be coded.
My first attempt to do this, however, fell a little flat. I put the Command definition on the ViewModel, where it belongs. But when it came to implementing the CommandBindings for the command, I ran into problems. The various command delegates should logically be defined in the ViewModel as well, but I found that the XAML didn’t like wiring it this way (maybe it can do it and I didn’t persist in figuring out what the issue was long enough, but I wanted to get things done and not spelunk into code through Reflector). I knew John Gossman discussed doing this, so I inspected his example code. To be honest, I didn’t totally like what he’d done. He abstracted out commands into a CommandModel with virtual methods you could override for the delegates on the CommandBinding. But the actions taken by the commands is almost certainly going to require knowledge of the ViewModel. I didn’t want to create objects with this kind of coupling, especially when the functionality seemed to belong on the ViewModel not on a CommandModel. So, I hacked his code to turn it "inside out". Here’s what I wound up with.
public class CommandModel { RoutedCommand command; ExecutedRoutedEventHandler executedHandler; CanExecuteRoutedEventHandler canExecuteHandler; public CommandModel(ExecutedRoutedEventHandler executedHandler) { command = new RoutedCommand(); this.executedHandler = executedHandler; } public CommandModel(ExecutedRoutedEventHandler executedHandler, CanExecuteRoutedEventHandler canExecuteHandler) { command = new RoutedCommand(); this.executedHandler = executedHandler; this.canExecuteHandler = canExecuteHandler; } public RoutedCommand Command { get { return command; } } virtual public void OnQueryEnabled(object sender, CanExecuteRoutedEventArgs e) { if (canExecuteHandler != null) { canExecuteHandler(sender, e); } else { e.CanExecute = true; e.Handled = true; } } virtual public void OnExecute(object sender, ExecutedRoutedEventArgs e) { executedHandler(sender, e); } }
This allows me to create the CommandModel within the ViewModel and tie it to event handlers within the ViewModel itself. I you want to use it in the way illustrated by Mr. Gossman, you still can, but I prefer the functionality to be in the ViewModel.
The only thing I’m left with that still feels a bit kludgy to me is the CreateCommandBinding class with the attached property used to wire up the actual CommandBinding through our CommandModel. But it works, so I’ll live with it until I find a more elegant (to my eye) solution.

http://www.batteries-shop.nethttp://www.batterieslaptop.nethttp://www.uk-laptopbattery.comhttp://www.wt-batteries.comhttp://www.cheapteastore.comhttp://www.laptopbatterystore.co.ukhttp://www.batterieslaptop.nethttp://www.batteries-supply.comhttp://www.powertoolsbatteries.co.ukhttp://www.batterygrip.orghttp://www.uk-batteries.co.ukhttp://www.ukbatterystore.co.ukhttp://www.topbatteries.co.ukhttp://www.batteries-shop.net/acer-laptop-battery-c-2.htmlhttp://www.batteries-shop.net/apple-laptop-battery-c-3.htmlhttp://www.batteries-shop.net/asus-laptop-battery-c-4.htmlhttp://www.batteries-shop.net/compaq-laptop-battery-c-5.htmlhttp://www.batteries-shop.net/dell-laptop-battery-c-6.htmlhttp://www.batteries-shop.net/fujitsu-laptop-battery-c-7.htmlhttp://www.batteries-shop.net/gateway-laptop-battery-c-8.htmlhttp://www.batteries-shop.net/hp-laptop-battery-c-9.htmlhttp://www.batteries-shop.net/hp-compaq-laptop-battery-c-10.htmlhttp://www.batteries-shop.net/ibm-laptop-battery-c-11.htmlhttp://www.batteries-shop.net/lenovo-laptop-battery-c-12.htmlhttp://www.batteries-shop.net/lg-laptop-battery-c-13.htmlhttp://www.batteries-shop.net/panasonic-laptop-battery-c-14.htmlhttp://www.batteries-shop.net/samsung-laptop-battery-c-15.htmlhttp://www.batteries-shop.net/sony-laptop-battery-c-16.htmlhttp://www.batteries-shop.net/toshiba-laptop-battery-c-17.htmlhttp://www.uk-laptopbattery.com/acer-laptop-battery-c-2.htmlhttp://www.uk-laptopbattery.com/apple-laptop-battery-c-3.htmlhttp://www.uk-laptopbattery.com/asus-laptop-battery-c-4.htmlhttp://www.uk-laptopbattery.com/compaq-laptop-battery-c-5.htmlhttp://www.uk-laptopbattery.com/dell-laptop-battery-c-6.htmlhttp://www.uk-laptopbattery.com/fujitsu-laptop-battery-c-7.htmlhttp://www.uk-laptopbattery.com/gateway-laptop-battery-c-8.htmlhttp://www.uk-laptopbattery.com/hp-laptop-battery-c-9.htmlhttp://www.uk-laptopbattery.com/hp-compaq-laptop-battery-c-10.htmlhttp://www.uk-laptopbattery.com/ibm-laptop-battery-c-11.htmlhttp://www.uk-laptopbattery.com/lenovo-laptop-battery-c-12.htmlhttp://www.uk-laptopbattery.com/lg-laptop-battery-c-13.htmlhttp://www.uk-laptopbattery.com/panasonic-laptop-battery-c-14.htmlhttp://www.uk-laptopbattery.com/samsung-laptop-battery-c-15.htmlhttp://www.uk-laptopbattery.com/sony-laptop-battery-c-16.htmlhttp://www.uk-laptopbattery.com/toshiba-laptop-battery-c-17.htmlhttp://www.topbatteries.co.uk/acer-laptop-battery-c-1.htmlhttp://www.topbatteries.co.uk/hp-laptop-batteries-c-2.htmlhttp://www.topbatteries.co.uk/sony-laptop-battery-c-3.htmlhttp://www.topbatteries.co.uk/dell-laptop-battery-c-4.htmlhttp://www.topbatteries.co.uk/ibm-laptop-battery-c-5.htmlhttp://www.topbatteries.co.uk/compaq-laptop-battery-c-6.htmlhttp://www.topbatteries.co.uk/toshiba-laptop-battery-c-7.htmlhttp://www.topbatteries.co.uk/fujitsu-laptop-battery-c-8.htmlhttp://www.topbatteries.co.uk/apple-laptop-battery-c-9.htmlhttp://www.topbatteries.co.uk/samsung-laptop-battery-c-10.htmlhttp://www.cheapteastore.com/chinese-black-tea-c-3.htmlhttp://www.cheapteastore.com/chinese-herbal-tea-c-7.htmlhttp://www.cheapteastore.com/chinese-oolong-tea-c-2.htmlhttp://www.cheapteastore.com/chinese-puerh-tea-c-4.htmlhttp://www.cheapteastore.com/chinese-white-tea-c-5.htmlhttp://www.cheapteastore.com/chinese-yellow-tea-c-6.htmlhttp://www.cheapteastore.com/tie-guan-yin-c-8.html