(Blogging Tunes: Burton - Corea - Metheny - Haynes - Holland: "Like Minds")

My buddy Nick Kramer over on the WPF team was writing a recap of the recent PDC in his blog a while back and he made some comments that I think I should chime in about.  Nick was referring to my presentation on Windows Forms and WPF Interoperability and he commenting that he really didn't like the idea that I was showing how to use Windows Forms controls via XAML.  His basic beef about this seems to be that he thinks code is a better way to do when using Windows Forms controls in a WPF application as it is a more natural fit since that's how Windows Forms was meant to be (and frankly designed to be) used.

Well, I gotta say that I can't agree more Nick!  I'm totally with you on that point.  Windows Forms was designed and developed assuming a purely code based model, not a mark-up based model.  So, if I agree, then why do I constantly talk about using XAML for Windows Forms controls.  Well, there are a few reasons really.  First of all, if you are going to write a WPF application then you have no choice but to learn and use XAML.  Now, that's most likely a temporary thing until we get a nice set of designers out there for WPF that will "emit XAML out the back end".  (One of my QA buddies in the Windows Forms team, Andrew Downum gets a kick out of that phrase when I use it).  And Microsoft has already discussed our plans for releasing these product in the Orcas time frame.  And in the meantime there are third-party XAML designers out there like Aurora from Mobiform.  But my point here is that if XAML is going to be in your face, and is the primary way people are going to work with the UI of their WPF application (for now), then it only makes sense to make sure they understand that they can also use XAML to work with Windows Forms controls as well.  Another reason is that frankly XAML is one of the current buzzwords and hot topics out there and I guess I'm shamelessly jumping on that train and riding that bad boy as far as I can :)  And finally, I also tend to do this to illustrate how the XAML parser was not developed strictly to support WPF UI "goo".  It is basically a general purpose markup language for working with CLR types.  That's why in my demos, I tend to show how you can instantiate basic CLR types like strings using XAML.  I'm simply showing that you don't have to think of XAML as just for WPF elements.

Having said all of that, let me clarify some points about using XAML to describe Windows Forms:

  1. You do not have to use XAML to define Windows Forms controls in a WPF application
  2. You can choose to use XAML to define Windows Forms controls in a WPF application
  3. You can choose to strictly use code in the code behind files to define Windows Forms controls in a WPF application
  4. It is generally a better choice to use strictly code for Windows Forms controls
  5. There are limitations in XAML that make it impossible to do some Windows Forms related things using XAML and you will be forced to use code for these exceptions
  6. While you can use XAML to describe Windows Forms controls in a WPF application, you CANNOT use XAML to describe a complete Windows Forms application outside the scope of WPF.

So let's do some comparisons here.  Let's look at how you can work with Windows Forms controls from both XAML and code behind.  (But first I have to change music because the stuff I was listening to just finished...Okay, I'll go with Joni Mitchell's "Hejira", which really kicks ass and features Jaco Pastorius who is just about without a doubt the world's greatest bass player) 

Okay, where was I...Oh yeah, XAML vs. code.  Let's start with the idea of putting some Windows Forms controls in a WPF application.  Doesn't really matter what we choose here so I just make it easy and choose a good ol' button.  So using XAML, it would look something like:

<?Mapping XmlNamespace="wfi" ClrNamespace="System.Windows.Forms.Integration" Assembly="WindowsFormsIntegration"?>
<?
Mapping XmlNamespace="wf" ClrNamespace="System.Windows.Forms" Assembly="System.Windows.Forms"?>
<
Window x:Class="AvalonApplication23.Window1"
     xmlns=http://schemas.microsoft.com/winfx/avalon/2005
     xmlns:x=http://schemas.microsoft.com/winfx/xaml/2005
     xmlns:wfi="wfi"
     xmlns:wf="wf"
     Title="AvalonApplication23"
     >
     <
Grid>
          <
wfi:WindowsFormsHost>
               <
wf:Button Text="Windows Forms Button"/>
          </
wfi:WindowsFormsHost>
     </
Grid>
</
Window>

Now, let's do the same thing except let's not use XAML at all to define the Windows Forms stuff, let's do it all in code.  So we will need to modify the XAML to rip out what we just put in so that it looks like this:

<Window x:Class="AvalonApplication23.Window1"
     xmlns=http://schemas.microsoft.com/winfx/avalon/2005
     xmlns:x=http://schemas.microsoft.com/winfx/xaml/2005 
     Title="AvalonApplication23"
     Loaded="WindowLoaded" 
     >
     <
Grid x:Name="grid1"

     </Grid>
</
Window>

Notice that we gave the Grid tag a name, "grid1".  There is a specific reason for this.  It will make it easier for us to add child controls to the grid using code (which is what we're just about to do).  Now let's see what the code looks like:

private void WindowLoaded(object sender, RoutedEventArgs e)
{
     WindowsFormsHost host = new WindowsFormsHost();
     System.Windows.Forms.
Button wfButton = new System.Windows.Forms.Button();
     wfButton.Text =
"Windows Forms Button";
     host.Children.Add(wfButton);
     this.grid1.Children.Add(host);

}

So as you can see, you really have two options here, XAML or code.  Damn, it just started raining outside...I'm gonna get wet riding home on the Harley later on.