我认为您的问题的解决方案相当容易。
简而言之,您正在创建一个 ViewModel 作为 Shell,当应用程序启动时,它用登录窗口表示。如果用户成功登录,此窗口将关闭,并且视图模型的相同实例将显示在内容窗口中。如果用户正在注销,则会再次显示登录窗口。
首先创建一个接口 IShell,它公开两个委托LoginSuccessful
和Logout
public interface IShell
{
Action LoginSuccessful { get; set; }
Action Logout { get; set; }
}
接下来创建一个ShellViewModel
实现的类IShell
public class ShellViewModel : Screen, IShell
{
public ShellViewModel()
{
LoginSuccessful = delegate { };
Logout = delegate { };
}
public Action LoginSuccessful { get; set; }
public Action Logout { get; set; }
public void DoLogin()
{
LoginSuccessful();
}
public void DoLogout()
{
Logout();
}
}
方法DoLogin
和DoLogout
是可以绑定到Button
适合您的控件或任何控件的操作。
下一步是覆盖OnStartupMethod
Bootstrapper 中的 。前提是您拥有一个实例WindowManager
并由ShellViewModel
您选择的 IoC 框架导出。
protected override void OnStartup(object sender, StartupEventArgs e)
{
var windowManager = IoC.Get<IWindowManager>();
var viewModel = IoC.Get<IShell>();
viewModel.LoginSuccessful =
() => GuardCloseAndReopen("Content");
viewModel.Logout =
() => GuardCloseAndReopen("Login");
windowManager.ShowWindow(viewModel, "Login");
}
private void GuardCloseAndReopen(string shellViewMode)
{
var windowManager = IoC.Get<IWindowManager>();
var shellScreen = IoC.Get<IShell>() as Screen;
Application.ShutdownMode = ShutdownMode.OnExplicitShutdown;
shellScreen.TryClose();
Application.ShutdownMode = ShutdownMode.OnLastWindowClose;
windowManager.ShowWindow(shellScreen, shellViewMode);
}
诀窍是:如果调用该方法,DoLogout
当前窗口会通过调用TryClose
. ShellViewModel
同时,您可以通过将 设置为Application.ShutdownMode
来防止应用程序被关闭OnExplicitShutdown
。然后使用窗口管理器,通过将“登录”作为上下文信息传递给窗口管理器,以登录模式创建另一个窗口。这实际上是同一个 ViewModel,但是具有不同的视觉表示。
因为Logout
你正在做同样的事情。
要使用 Caliburn 约定来完成这项工作,您需要一个特殊的项目结构,如此处所示(并在此处解释):
现在我挑战您获取这段代码并创建一个小示例应用程序。创建一个Login
视图(使用按钮登录或其他)并Content
使用 LoginSuccessful/ Logout 方法创建一个带有注销按钮的视图。
这将用最少的代码和类解决您的问题。希望这对您有所帮助。