0

我正在使用 Caliburn Micro 并有一个在启动时显示的登录视图模型。

我正在使用一个单独的类来处理与服务器的所有连接并向 ViewModel 提供简单的回调事件,这就是 ITransportClient。

用户输入他们的凭据,点击登录,对话框显示连接过程以及多个状态(连接、验证用户名、下载配置)。在后台,登录 ViewModel 将调用ITransportClient.Login().

如果登录成功并且所有步骤都已完成,则应关闭表单并打开主窗口 ViewModel。如果凭据不正确或下载设置有问题,应显示错误并保留登录表单。

如果与服务器的连接丢失(通过 ITransportClient 事件指示),则应用程序应尝试重新连接多次,如果服务器在可配置的时间段内保持脱机状态,则应再次显示登录窗口。

  1. 根据上述流程,我将如何最好地处理登录对话框和主窗口之间的切换?
  2. 登录 ViewModel 如何自行关闭,我只看到hasIWindowManagerShowDialog方法?ShowPopupShowWindow
  3. 将上述内容分开的最佳方法是什么,允许在 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);
        }
    }
}
4

1 回答 1

1

CM通过IWindowManager接口提供CM能理解的窗口管理契约。实现本身是 UI 特定的东西 - 例如 Telerik 控件与 Microsoft 标准控件 = 不同。IWindowManager在 CM 中实现,WindowManager并且该管理器包含一个名为的子类WindowConductor,其工作是处理来自Window控件本身的事件并将调用传递给窗口(它是视图模型和视图容器之间的粘合剂)

看一看:

http://caliburnmicro.codeplex.com/SourceControl/changeset/view/35f41b2f9113#src%2fCaliburn.Micro.Silverlight%2fWindowManager.cs

该指挥器为您管理窗口 - 如果您查看实现,您可以看到它检查某些接口的存在,IActivate例如IDeactivateIGuardClose。如果您实现这些接口,您的窗口将获得更多生命周期功能。

继承 fromScreen而不是PropertyChangedBase免费获得这些接口实现的一种方法,您还可以获得IViewAware提供自动视图缓存和获取视图引用的有用方法的实现

一旦你继承了这个类或实现了接口,你就可以通过VM调用方法来关闭窗口(例如TryClose)。它将负责将WindowConductor必要的调用传递给窗口控件,您甚至可以使用IGuardClose允许您取消关闭操作的接口来防止窗口关闭。

我假设您已经掌握了ActionsCM,因为您的 VM 上似乎有登录方法。

现在这更像是一个答案中的问题 - 你需要走弹出窗口路线吗?你可以继承Conductor<T>.Collections.OneActive并调用ActivateItem(yourViewModel)T可以IScreen)。当新项目被激活时,您的登录视图模型将自动停用,或者您可以打开登录失败的视图模型或类似的东西。虽然这不使用单独的窗口,但实现非常简单,只需将 a 绑定ContentControlActiveItem您的导体视图模型上

在这里查看详细信息(查看简单 MDI 部分和周边):

http://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition&referringTitle=Documentation

于 2012-12-04T00:18:22.273 回答