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