我正在使用 Caliburn Micro 并有一个在启动时显示的登录视图模型。
我正在使用一个单独的类来处理与服务器的所有连接并向 ViewModel 提供简单的回调事件,这就是 ITransportClient。
用户输入他们的凭据,点击登录,对话框显示连接过程以及多个状态(连接、验证用户名、下载配置)。在后台,登录 ViewModel 将调用ITransportClient.Login()
.
如果登录成功并且所有步骤都已完成,则应关闭表单并打开主窗口 ViewModel。如果凭据不正确或下载设置有问题,应显示错误并保留登录表单。
如果与服务器的连接丢失(通过 ITransportClient 事件指示),则应用程序应尝试重新连接多次,如果服务器在可配置的时间段内保持脱机状态,则应再次显示登录窗口。
- 根据上述流程,我将如何最好地处理登录对话框和主窗口之间的切换?
- 登录 ViewModel 如何自行关闭,我只看到has
IWindowManager
和ShowDialog
方法?ShowPopup
ShowWindow
- 将上述内容分开的最佳方法是什么,允许在 Login ViewModel 外部关闭登录窗口,并在用户注销主窗口时显示登录窗口?这应该在引导程序中完成,还是应该为此创建一个单独的 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);
}
}
}