從零開始搭建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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM