私は古いwinformsプログラムをMVVMにCaliburn Micro、DIにNinjectを利用するWPFにアップグレード中です。
ソリューションを、Caliburn Micro ブートストラップの非汎用実装を実行する WPF ソリューションに更新しました。現在、実行するベースの ShellViewModel がないため、これを行います。
私は Ninject にかなり精通しているので、標準の Caliburn Micro ブートストラップではなく、Ninject フレーバーのブートストラップを使用しています。
ブートストラップは次のようになります。
public class NinjectBootstrapper : Bootstrapper
{
private const string EXTENSION_PATH = "Plugins";
public static IKernel Kernel;
protected override void Configure()
{
Kernel = new StandardKernel();
Kernel.Bind<IEventAggregator>()
.To<EventAggregator>()
.InSingletonScope();
Kernel.Bind<ViewModels.IAnalysisOutputTableViewModel>()
.To<ViewModels.AnalysisOutputTableViewModel>()
.InSingletonScope();
Kernel.Bind<IWindowManager>()
.To<WindowManager>()
.InSingletonScope();
Kernel.Bind<FormMain>()
.ToSelf();
}
protected override object GetInstance(Type serviceType, string key)
{
if (serviceType != null)
{
return Kernel.Get(serviceType);
}
throw new ArgumentNullException("serviceType");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return Kernel.GetAll(service);
}
protected override void BuildUp(object instance)
{
Kernel.Inject(instance);
}
}
メイン フォームを起動するために、App.xaml.cs で OnStartup を次のようにオーバーライドする必要がありました。
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
NinjectBootstrapper.Kernel.Get<FormMain>().Show();
}
}
上記で明らかなように、メインの Ninject カーネルを public static として公開してアクセスできるようにしましたが、これはおそらくアンチパターンであることを認識しています。プログラムの変換が完了したら、これを解決します。
適切な MVVM を使用して、メイン フォームの新しい子ウィンドウを実装しました。次のようなボタンからウィンドウを開く必要があります。
private void dataViewerButton_Click(object sender, EventArgs e)
{
windowManager.ShowWindow(analysisOutputTableViewModel);
}
ここまでは順調ですね。
問題は、この子ウィンドウを閉じようとしたときです。ウィンドウを閉じるだけでなく、プログラム全体をシャットダウンします。
これは、この子ウィンドウが Caliburn が処理する唯一のウィンドウ (またはビュー) であるため、非アクティブ化されると、Caliburn がプログラムを閉じたいと判断したためだと思います。
この自動クローズ動作を停止する方法はありますか? おそらく、メインフォームを初期化する別の方法でしょうか?
アップデート
以下の Marwijn の回答を使用して、アプリケーションを適切に閉じることができました。
最後にApplication.Exit();
、メイン フォームの Closing イベントで使用しました。
private void Form_Main_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
私のApp.xaml.csへの次の変更と組み合わせて:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainForm = NinjectBootstrapper.Kernel.Get<FormMain>();
mainForm.Show();
mainForm.FormClosed += mainForm_FormClosed;
}
void mainForm_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
{
this.Shutdown(0);
}
}
Caliburn Micro と Ninject を使用してメイン フォームから WPF ウィンドウをロードできるようになりました。すべてが適切にシャットダウンされ、プロセスが実行されたままになることはありません。このソリューションは、メイン フォームを WPF に更新できるようになるまでうまくいくようです。