从零开始搭建Wpf基础8-登录界面成功后显示主窗体

AIStudio框架汇总及介绍

前言:1.将登录界面放在独立窗体中,登录后显示主窗体 2.将启动工程与其它界面分离出来,以便插件可以在不同的工程中复用。

第一步:1.新建一个Wpf类库AIStudio.Wpf.Home,主要插件的容器在这里。2.建立文件夹Views,ViewModels.3.将原先工程下的IntroduceView和IntroduceViewModel移动到对应文件夹,并改成命名空间AIStudio.Wpf.Client替换成AIStudio.Wpf.Home,在项目内批量替换。4.添加缺失的项目引用。5.将TitleViewModel移动到AIStudio.Core工程的新建文件夹ViewModels下。

好了,编译一下。(将该添加的项目引用添加,或者安装Prism,因为命名空间改变了,请耐心逐个报错处理,保证编译通过) 编译通过后,运行,和之前一样的效果。(因为我们只是调整了一下结构)

第二步;1.在AIStudio.Wpf.Client工程下的Views中新建一个LoginWindow窗口,将LoginView嵌入在里面。2.将MainWindowModule中的注册LoginView去除

<Window x:Class="AIStudio.Wpf.Client.Views.LoginWindow"
        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:AIStudio.Wpf.Client.Views"
        mc:Ignorable="d"
        Title="LoginWin" Height="350" Width="500">
    <Grid>
        <local:LoginView></local:LoginView>
    </Grid>
</Window>
public void OnInitialized(IContainerProvider containerProvider)
{
    var regionManager = containerProvider.Resolve<IRegionManager>();
    //regionManager.RegisterViewWithRegion("MainContentRegion", typeof(LoginView));
}

第三步:在启动主窗口前先启动LoginWindow,在App.xaml.cs的CreateShell创建如下代码:

protected override void InitializeShell(Window shell)
{
    //登录
    LoginWindow login = new LoginWindow();
    if (login.ShowDialog() == false)
    {
        if (Application.Current != null)
        {
            Application.Current.Shutdown();
        }
        return;
    }

    base.InitializeShell(shell);
}

prism在主窗体显示之前会调用这个方法,这个方法返回后才显示主窗体。 好了,先运行一下。 显示出来了,但是点击按钮没有反应,因为ViewModel没有绑定上,LoginView.xaml中添加

xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"

好了,有了,但是点击登录没有自动跳转,因为login.ShowDialog()。所以需要实现返回DialogResult,还要关闭窗口Close.

第四步:LoginCommand中添加参数,将窗体传递到ViewModel

<Button Grid.Row="3" Grid.ColumnSpan="2" Content="登录" Command="{Binding LoginCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" IsDefault="True" />

因为Comand没有直接在窗口中,在自定义控件中,可以使用RelativeSource查找的方法找到窗口。 ViewModel接收参数,进行处理。

private ICommand _loginCommand;
public ICommand LoginCommand
{
    get
    {
        return this._loginCommand ?? (this._loginCommand = new DelegateCommand<Window>(para => this.Login(para)));
    }
}



private async void Login(Window window)
{
    if (!string.IsNullOrEmpty(UserName)  && !string.IsNullOrEmpty(Password))
    {
        var mD5Password = Password.ToMD5String();
        var token = await _dataProvider.GetToken(ServerIP, UserName, mD5Password);
        if (!token.Success)
        {
            MessageBox.Show(token.Msg);
            return;
        }

        window.DialogResult = true;
        window.Close();

        //_regionManager.RegisterViewWithRegion("MainContentRegion", nameof(IntroduceView));
    }
    else
    {
        MessageBox.Show("请输入用户名或密码!");
    }


}

为什么注释掉_regionManager.RegisterViewWithRegion("MainContentRegion", nameof(IntroduceView));这个呢,因为主窗体还未显示MainContentRegion区域还没有初始化,所以不会生效。 将其移动到MainWindowModule中好了,替换之前LoginView的位置。

public class MainWindowModule : IModule
{
    public void OnInitialized(IContainerProvider containerProvider)
    {
        var regionManager = containerProvider.Resolve<IRegionManager>();
        //regionManager.RegisterViewWithRegion("MainContentRegion", typeof(LoginView));

        regionManager.RegisterViewWithRegion("MainContentRegion", nameof(IntroduceView));
    }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<IntroduceView>();
    }
}

运行一下:

好了,是不是就达到了我们登录的效果了。

源码地址:https://gitee.com/akwkevin/aistudio.-wpf.-client.-stepby-step

每一章都有自己的Tag,按照链接进去直接下载就是本章内容。

另外推荐一下我的Wpf客户端框架:https://gitee.com/akwkevin/aistudio.-wpf.-aclient

posted @ 2021-08-14 08:21  竹天笑  阅读(1996)  评论(1编辑  收藏  举报