Friday, February 05, 2010

Using Caliburn inside of Windows Forms with WPF UserControls/ElementHost

I'm working to have a little MVVM action inside of our application, but it's Windows Forms, so I am using an ElementHost to get the WPF UserControl objects loaded. There are aspects to MVVM that cry out for frameworks to help you (binding double-click events to ListViewItem objects being one important one for me). I tried about a million things to get the very powerful Caliburn WPF application framework to do something--anything--in this hybrid context. It was the last thing I tried that worked! ;)

There seem to be two key things you must do to get Caliburn properly registered and listening in this context:
  1. You have to use the "WithAssemblies" option on the framework configuration call, passing in a reference to the current assembly, along with the "WithPresentationFramework" call.
  2. You must spin up Caliburn before the entry point UserControl is initialized and assigned to the ElementHost. If the UserControl is set as the Child via the Windows Forms designer, this means that you must initialize Caliburn in the Form containing the ElementHost's constructor before its InitializeComponent call.
    public partial class Form1 : Form
    {
        public Form1()
        {
            CaliburnFramework.ConfigureCore()
                .WithAssemblies(System.Reflection.Assembly.GetExecutingAssembly())
                .WithPresentationFramework()
                .Start();
            InitializeComponent(); // must come after the above
        }
    }

I went down several dead-ends before discovering this, such as thinking I needed a non-null System.Windows.Application.Current class, thinking I needed to initialize the framework inside of the UserControl's constructor, etc. I hope this helps someone.

You can download the sample application here.