zoukankan      html  css  js  c++  java
  • 从零开始搭建Wpf基础8-登录界面成功后显示主窗体

    前言: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

    作者:竹天笑
    互相学习,提高自己。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    线程执行android的looper,handler消息小结
    类型对象phonegap入门10 Contacts
    域名查询普及一下域名知识
    类数据[Android Training视频系列] 6.3 Saving Data in SQL Databases(保存数据到SQLite)
    概率初始化hdu 2955 (01背包变形)
    类最大hdu 1792 A New Change Problem
    标签定义jQuery 入门教程(41): jQuery UI Tab 示例(一)
    nullnullOptimizing Navigation for TV 优化电视导航
    nullnullHandling Features Not Supported on TV 在电视上处理不支持的功能
    nullnullLoading Large Bitmaps Efficiently 有效的处理较大的位图
  • 原文地址:https://www.cnblogs.com/akwkevin/p/15139826.html
Copyright © 2011-2022 走看看