I'm fortunate enough to be attending DevWeek 2008 this week. Today I took in 3 WPF-related sessions by Dave Wheeler (who also presented yesterday's excellent keynote on Silverlight). The talk that was of the most interest to me, and probably to many other people, covered using WPF and Windows Forms together. My current project has got far too much Windows Forms code to consider a re-write at this stage, but there are a couple of interface features I'd like to implement which will be much easier in WPF. It seems this is fairly straightforward (unlike interop between WPF and Win32/MFC, which made me glad I left all that behind).
One of the caveats Dave mentioned was that the ShowDialog method in the Windows Forms Form class requires an IWin32Window type as its argument, and WPF controls don't implement that type or, indeed, have an IntPtr handle. He presented a shim solution which uses the WindowInteropHelper to provide a surrogate handle for WPF Window types:
class Shim : IWin32Window
{
public Shim(System.Windows.Window owner)
{
// Create a WindowInteropHelper for the WPF Window
interopHelper = new WindowInteropHelper(owner);
}
private WindowInteropHelper interopHelper;
#region IWin32Window Members
public IntPtr Handle
{
get
{
// Return the surrogate handle
return interopHelper.Handle;
}
}
#endregion
}
This set off my current obsession with extension methods, so I scribbled one to wrap this technique, tested it when I got home and it worked fine. Here it is:
namespace System.Windows.Forms
{
public static class WPFInteropExtensions
{
public static DialogResult ShowDialog(
this System.Windows.Forms.Form form,
System.Windows.Window owner)
{
Shim shim = new Shim(owner);
return form.ShowDialog(shim);
}
class Shim : IWin32Window
{
// as above
}
}
}