Следуя принятому ответу (хороший!), Я хотел бы показать вам, как реализовать загрузчик WinForms в подходе ViewModel First таким образом:
- Вы выигралине нужно создавать окно WPF и,
- Вам не нужно будет привязываться напрямую к ViewModel из View.
Для этого нам нужно создать нашу собственную версиюWindowManager, убедитесь, что мы не вызываем метод Show
в Window (если это применимо к вашему случаю), и разрешаем привязку происходить.
Вот полный код:
public class WinformsCaliburnBootstrapper<TViewModel> : BootstrapperBase where TViewModel : class
{
private UserControl rootView;
public WinformsCaliburnBootstrapper(ElementHost host)
: base(false)
{
this.rootView = new UserControl();
rootView.Loaded += rootView_Loaded;
host.Child = this.rootView;
Start();
}
void rootView_Loaded(object sender, RoutedEventArgs e)
{
DisplayRootViewFor<TViewModel>();
}
protected override object GetInstance(Type service, string key)
{
if (service == typeof(IWindowManager))
{
service = typeof(UserControlWindowManager<TViewModel>);
return new UserControlWindowManager<TViewModel>(rootView);
}
return Activator.CreateInstance(service);
}
private class UserControlWindowManager<TViewModel> : WindowManager where TViewModel : class
{
UserControl rootView;
public UserControlWindowManager(UserControl rootView)
{
this.rootView = rootView;
}
protected override Window CreateWindow(object rootModel, bool isDialog, object context, IDictionary<string, object> settings)
{
if (isDialog) //allow normal behavior for dialog windows.
return base.CreateWindow(rootModel, isDialog, context, settings);
rootView.Content = ViewLocator.LocateForModel(rootModel, null, context);
rootView.SetValue(View.IsGeneratedProperty, true);
ViewModelBinder.Bind(rootModel, rootView, context);
return null;
}
public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
CreateWindow(rootModel, false, context, settings); //.Show(); omitted on purpose
}
}
}
Надеюсь, это поможет кому-то с такими же потребностями.Это точно спасло меня.