c# - 主窗口之前的 WPF PRISM 7 登录窗口
问题描述
我是 WPF/Prism 的新手,我正在尝试执行以下操作:我需要在启动主窗口之前加载登录视图(窗口或用户控件)。成功登录后,删除登录视图并转到 Main Mindow。
我在这里查看了几个答案,但所有答案都在使用 boostrapper 类引用旧版本的 PRISM。
我有一个 WPF (Prism 7) 应用程序,其中包含主项目和一个授权模块。
从我的主项目 App.xaml.cs
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<AuthorizationModule>();
}
在授权模块中,我有我的 LoginView / LoginViewModel。授权模块注册一个 LoginService 将被注入到 LoginViewModel
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register(typeof(ILoginService), typeof(LoginService));
}
LoginViewModel 将负责使用此 LoginService 对用户进行身份验证。
我看到的部分答案显示如下:
protected override void InitializeShell()
{
Window login = new LoginView();
var loginVM = new LoginViewModel(new LoginAuth());
loginVM.LoginCompleted += (sender, args) =>
{
login.Close();
Application.Current.MainWindow.Show();
};
login.DataContext = loginVM;
// problem below:
login.ShowDialog();
}
但是,这似乎有点不必手动实例化 LoginView 而不是让容器为您做这件事。
此外,PRISM 7 上的 InitiallizeShell 期望创建当前的 shell。我不确定是否应该使用传递给激活主窗口的这个值。
protected override void InitializeShell(Window shell)
我还在 Github 上阅读了 Brian Lagunas 本人的文章,可能会使用 EventAggregator(我已经尝试过)。我已经让授权模块注册了 EventAggregator 并从 LoginViewModel 成功登录后,发布了 SuccessLoginEvent 但我可以弄清楚如何从主应用程序订阅该事件
所以基本上预期的结果是,当应用程序启动时,如果用户未登录,则显示 LoginView,在用户对其进行身份验证后,将他带到已加载所有需要的模块的 MainWindow。
任何帮助将不胜感激。
解决方案
我尝试了一下,并提出了以下建议:
应用程序:
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<Login>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register(typeof(object), typeof(Login), "Login");
containerRegistry.RegisterInstance(typeof(LoginViewModel), new LoginViewModel(Container.GetContainer(), Container.Resolve<RegionManager>()));
containerRegistry.Register(typeof(object), typeof(MainWindow), "MainWindow");
containerRegistry.RegisterInstance(typeof(MainWindowViewModel), new MainWindowViewModel(Container.GetContainer(), Container.Resolve<RegionManager>()));
}
}
XAML:
<Window x:Class="LoginTest.Views.Login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LoginTest.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="Login" Height="250" Width="400">
<Grid>
<Button Content="Login" HorizontalAlignment="Left" Height="61" Margin="100,100,0,0" VerticalAlignment="Top" Width="164" Command="{Binding LoginCommand}"/>
</Grid>
代码隐藏:
public partial class Login : Window
{
public Login()
{
InitializeComponent();
((LoginViewModel)DataContext).NewWindow += StartMainApp;
((LoginViewModel)DataContext).CloseWindow += CloseWindow;
}
private void StartMainApp(Object win)
{
Application.Current.MainWindow = (Window)win;
Application.Current.MainWindow.Show();
}
private void CloseWindow()
{
this.Close();
}
}
视图模型:
class LoginViewModel : BindableBase
{
private readonly IUnityContainer _container;
private readonly IRegionManager _regionManager;
private PrismApplication _application;
private string _title = "Prism Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public DelegateCommand LoginCommand { get; set; }
public delegate void NewWindowDelegate(Object win);
public delegate void CloseWindowDelegate();
public CloseWindowDelegate CloseWindow{ get; set; }
public NewWindowDelegate NewWindow { get; set; }
public LoginViewModel(IUnityContainer container, IRegionManager regionManager)
{
_regionManager = regionManager;
_container = container;
LoginCommand = new DelegateCommand(OnLogin);
}
private void OnLogin()
{
Trace.WriteLine("Logging in");
// do your login stuff
// If Login OK continue here
NewWindow.Invoke(_container.Resolve<MainWindow>());
CloseWindow.Invoke();
}
}
我希望我的例子有任何用处!
推荐阅读
- powerbi - Power BI 中的条件转换数据
- javascript - 通过 viewBox 操作 svg
- docker - Docker-compose:从第三个容器中嗅探两个容器之间的包
- sql - 使用 REGEXP_SUBSTR 将值插入多个列
- salesforce - Salesforce 使用 apex 程序停用最近 3 个月未登录的 Salesforce 用户
- firebase - 托管在 Firebase 存储中的图像会触发 gmail 的垃圾邮件过滤器
- c# - 尝试在 Visual Studio Code 中创建 webapi 时出错
- c# - OledbConnection,缺少读取 600 多于服务器上的行
- laravel - 如何在 laravel 中使用与关系获取 3 个表中的数据
- excel - 保存后 - 在新工作簿中创建 2 张不带公式的副本并另存为