Caliburn Micro を使用しており、起動時に表示されるログイン ビュー モデルがあります。
サーバーへのすべての接続を処理し、ViewModel への単純なコールバック イベントを提供する別のクラスを使用しています。これが ITransportClient です。
ユーザーが資格情報を入力してログインすると、ダイアログに接続プロセスがさまざまな状態 (接続、ユーザー名の検証、構成のダウンロード) に沿って表示されます。バックグラウンドで、Login ViewModel が を呼び出しITransportClient.Login()
ます。
正常にログインし、すべての手順が完了すると、フォームが閉じて、メイン ウィンドウの ViewModel が開きます。資格情報が正しくないか、設定のダウンロードに問題がある場合は、エラーが表示され、ログイン フォームが残ります。
サーバーへの接続が失われた場合 (ITransportClient イベントで示されます)、アプリケーションは何度も再接続を試行し、サーバーが構成可能な期間オフラインのままである場合は、ログイン ウィンドウを再度表示する必要があります。
- 上記のフローに従って、ログイン ダイアログとメイン ウィンドウの間の切り替えをどのように処理するのが最善でしょうか?
- どうすればログイン ViewModel を閉じることができます
IWindowManager
か?ShowDialog
ShowPopup
ShowWindow
- 上記を分離して、ログイン ビューモデルの外部でログイン ウィンドウを閉じ、ユーザーがメイン ウィンドウをログアウトしたときにログイン ウィンドウを表示できるようにする最善の方法は何ですか? これはブートストラップで行うべきですか、それとも別の ViewModel シェルを作成するべきですか?
私のブートストラッパー:
public class SimpleInjectorBootstrapper : Caliburn.Micro.Bootstrapper
{
private Container container;
protected override void Configure()
{
this.container = new Container();
this.container.Register<IWindowManager, WindowManager>();
this.container.Register<IEventAggregator, EventAggregator>();
this.container.Register<IAppViewModel, AppViewModel>();
this.container.Register<ILoginViewModel, LoginViewModel>();
this.container.RegisterSingle<ITransportClient, Transport.WCF.TransportClient>();
}
protected override object GetInstance(Type serviceType, string key)
{
return this.container.GetInstance(serviceType);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
base.OnStartup(sender, e);
var loginViewModel= this.container.GetInstance<ILoginViewModel>();
var windowManager = this.container.GetInstance<IWindowManager>();
windowManager.ShowWindow(loginViewModel);
}
}
私の LoginView モデルは以下のとおりです。
public class LoginViewModel : PropertyChangedBase, ILoginViewModel
{
private readonly ITransportClient transportClient;
private readonly IWindowManager windowManager;
private string connectionStatus;
public LoginViewModel(ITransportClient transportClient, IWindowManager windowManager)
{
this.transportClient = transportClient;
this.windowManager = windowManager;
this.transportClient.ConnectionEvent += new TransportConnectionEventHandler(UpdateStatusHandler);
}
public void Login()
{
// set from view, to be done via property, implement later
var username = "test";
var password = "test";
var result = this.transportClient.Login(username, password);
// if result is ok, we should close our viewmodel, however we
// cant call IWindowManager.Close(this) as only show methods exist
// perhaps this is better handled elsewhere?
}
public void UpdateStatusHandler(string status)
{
this.ConnectionStatus = status;
}
public string ConnectionStatus
{
get
{
return this.connectionStatus;
}
set
{
this.connectionStatus = value;
NotifyOfPropertyChange(() => ConnectionStatus);
}
}
}