前言:在C/S架构上,WPF无疑已经是“桌面一霸”了。在.NET生态环境中,很多小伙伴还在使用Winform开发C/S架构的桌面应用。但是WPF也有很多年的历史了,并且基于MVVM的开发模式,受到了很多开发者的喜爱。

并且随着工业化的进展,以及几年前微软对.NET平台的开源,国内大多数企业的工业系统或上位机系统,也慢慢从使用MFC、QT等C++平台,转向了.NET平台。并且.NET平台上,桌面应用上,WPF由于其独特的一些特性、以及可以制作动画、无损图像等,WPF的占比也越来越高。但是大多数小伙伴可能还是按照开发Winform的传统思路来开发WPF,所以这篇文章当做是一个使用MVVM模式开发的入门教程,希望大家在开发WPF的过程中,可以享受MVVM双向绑定的快乐。

本篇文章有关环境说明:

开发环境: VS 2022企业版

.NET版本环境:.NET 6

开发的操作系统环境:Win 10


1、先创建一个WPF应用程序,环境选择.NET 6

2、创建完成以后,如下图所示。

3、再新建一个WPF类库项目,用于存放所有第三方nuget包。此处纯个人习惯,用于防止多项目引用包的时候,产生包版本不一致的问题。

4、包项目里面,添加三个核心的包。分别是:Prism.Unity 、   Prism.Unity.Extensions   和  Unity.Microsoft.DependencyInjection

其中,Prism.Unity 、   Prism.Unity.Extensions  用于提供基础的Prism框架有关的环境以及Unity容器。Unity.Microsoft.DependencyInjection  用于提供可支持属性注入的方式,如果不使用属性注入,也可以不使用。

5、WpfDemo项目里面,引用刚刚的包项目后,修改App.xaml文件里面的默认配置项。以下是默认的内容:

6、替换为以下的内容。以下内容代表的是该程序引入prism框架。

7、App.cs类里面,继承改为PrismApplication,并且提供几个方法的重写。如果没有重写,可能会提示错误。

8、都载入以后,运行程序,就可以启动画面了。

9、项目新建Views文件夹和ViewModels文件夹。prism框架默认会自动识别存在Views文件夹的为视图端,ViewModels文件夹为VM端,用于自动双向绑定的匹配使用。

并且VM类与Views视图必须名称对应,VM类的结尾必须是xxxViewModel。

先建立一个登录页面,存放于Views文件夹下,然后页面引入prism框架所需的目录,如图所示。

同时设置了一个页面名称,该名称后面当做参数进行传递使用。

10、新建对应Login窗体的VM类 LoginViewModel,并且继承BindbleBase类,用于提供prism的双向绑定功能。

11、提供用户名、密码属性,以及用于按钮触发的事件属性。并且提供了一个模拟用户登录的方法。

12、在Login.xaml文件下,新增两个输入框和一个按钮,用于模拟用户登录功能和双向绑定功能。Mode=TwoWay的意思是,前端数据变更,会自动同步到后端绑定的属性上;后端绑定的属性如果被修改值了,也会传递到前端进行同步显示。还有其他的Mode,小伙伴们可以自行去尝试。

Command命令用于绑定事件属性,并且提供了一个参数,把当前页面当做参数传入进去,用于页面跳转使用;如果不需要参数的情况下,直接不需要CommandParameter属性就行。Command命令默认是鼠标单击事件,如果是其他事件需要实现,可以自定义做一些对应的事件的封装来进行实现。

其他说明:任意属性都是可以通过双向绑定进行实现的,包括控件名称、以下label控件的content属性、其他属性等等一系列。大佬们可以自行玩玩,此处提供简单案例,所以只对输入框的Text属性和按钮的点击事件提供了双向绑定的功能。

13、在App.cs类里面,提供InitializeShell方法的重写,并且注册Login页面。此处可以实现启动时候打开登录页面,通过提供DialogResult属性以后,就可以打开CreateShell方法里面注册的页面了。

14、现在运行程序,打开了登录页面,进行验证一下,如下图所示,说明验证生效了。输入正确的用户名和密码就可以进入到MainWindow页面。

15、接下来试试依赖注入的使用。先创建一个WPF类库项目,提供一个LoginService类与接口当做服务;并提供UserLogin方法的实现,如下图所示。

16、项目引用以后,提供属性注入。属性注入需要使用public,并且是属性,以及添加 Dependency的标记;如果是构造函数注入,则无需这些步骤。然后在登录方法里面,提供注入方法的使用,如下图所示。

17、在App.cs类里面,先前提供的重写方法 RegisterTypes方法里面,进行服务的注册。

以下提供了一个瞬时生命周期的注入,如下所示。如果要使用其他生命周期,大佬们可以自行研究,都是自带的,我就不多写了。

18、最后,运行程序,查看效果,程序运行符合预期,说明使用unity ioc容器进行服务注册成功。

19、 后记——有关代码奉上:

App.xaml 

<prism:PrismApplication x:Class="WpfDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfDemo"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources> </Application.Resources>
</prism:PrismApplication>

App.cs

 public partial class App : PrismApplication  // Application
{
public App() { } protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
} protected override void InitializeShell(Window shell)
{
if (Container.Resolve<Login>().ShowDialog() == false)
{
Application.Current?.Shutdown();
}
else
{
base.InitializeShell(shell);
}
} protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<ILoginService, LoginService>(); // 默认是transient注册 }
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{ }

LoginViewModel.cs

  public class LoginViewModel: BindableBase
{
[Dependency] // using Unity;
public ILoginService _loginService { get; set; } private string userName="";
private string password=""; public string UserName
{
get { return userName; }
set { SetProperty(ref userName, value); }
} public string Password
{
get { return password; }
set { SetProperty(ref password, value); }
} ICommand? loginCommand;
public ICommand LoginCommand {
get
{
if (loginCommand == null)
{
loginCommand = new DelegateCommand<object>(UserLogin); }
return loginCommand;
}
} void UserLogin(object obj)
{
if(!_loginService.UserLogin(this.UserName,this.Password))
{
MessageBox.Show("用户名或密码错误");
return;
}
(obj as Window).DialogResult = true; } }

Login.xaml

<Window x:Class="WpfDemo.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:WpfDemo.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d" Name="loginWindow"
Title="Login" Height="400" Width="600">
<Grid>
<Label Content="用户名" HorizontalAlignment="Left" Margin="56,119,0,0" VerticalAlignment="Top"/>
<Label Content="密码" HorizontalAlignment="Left" Margin="65,150,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Margin="112,124,0,0" TextWrapping="Wrap"
Text="{Binding UserName,Mode=TwoWay}" VerticalAlignment="Top" Width="143"/>
<TextBox HorizontalAlignment="Left" Margin="112,154,0,0" TextWrapping="Wrap"
Text="{Binding Password,Mode=TwoWay}" VerticalAlignment="Top" Width="143"/>
<Button Content="登录" HorizontalAlignment="Left" Margin="166,192,0,0"
Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=loginWindow}"
VerticalAlignment="Top" Height="24" Width="89"/> </Grid>
</Window>

LoginService.cs

 public class LoginService: ILoginService
{
public Boolean UserLogin(string userName, string password) {
if(userName =="wesky" && password == "123456")
{
return true;
}
else
{
return false;
}
} }

以上就是本篇文章的全部内容,欢迎大佬们点赞、评论或转发。如需转发,记得注明出处哟~ 谢谢大家围观。

【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入的更多相关文章

  1. 总结Unity IOC容器通过配置实现类型映射的几种基本使用方法

    网上关于Unity IOC容器使用的方法已很多,但未能做一个总结,故我这里总结一下,方便大家选择. 首先讲一下通过代码来进行类型映射,很简单,代码如下: unityContainer = new Un ...

  2. Unity IOC容器通过配置实现类型映射的几种基本使用方法

    网上关于Unity IOC容器使用的方法已很多,但未能做一个总结,故我这里总结一下,方便大家选择. 首先讲一下通过代码来进行类型映射,很简单,代码如下 unityContainer = new Uni ...

  3. Spring框架 之IOC容器 和AOP详解

    主要分析点: 一.Spring开源框架的简介  二.Spring下IOC容器和DI(依赖注入Dependency injection) 三.Spring下面向切面编程(AOP)和事务管理配置  一.S ...

  4. Ioc和DI之间的关系(依赖注入的核心概念)

    1.开篇闲话 由于之前做的很多项目都没接触到这个,后来到了另一个公司,他们的代码结构是基于领域驱动设计的,其中里面的对象都是通过依赖注入方式(Sprint.NET)实现的,也大致了解了哈,在网上搜了些 ...

  5. 控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI)

    控制反转(Inversion of Control,英文缩写为IoC),另外一个名字叫做依赖注入(Dependency Injection,简称DI),是一个重要的面向对象编程的法则来削减计算机程序的 ...

  6. 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定

    前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...

  7. Unity IOC容器的简单应用(转)

    转自:http://blog.csdn.net/wanzhuan2010/article/details/7763280 Unity是Unity是微软patterns& practices组用 ...

  8. Spring框架及IOC容器

    Spring是一个非常活跃的开源框架, 它是一个基于IOC和AOP来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.Spring以一种非侵入式的方式来管理你的代码, Spring提倡”最少 ...

  9. dreamvc框架(一)ioc容器的集成

    我的dreamvc框架最终写得差点儿相同了,借鉴了非常多开源框架,SpringMVC.Struts2等,眼下放在github上面.地址请猛戳我 写得差点儿相同了,是要写一个总结,把自己当时的思路记录下 ...

随机推荐

  1. 微信小程序入门教程之一:初次上手

    微信是中国使用量最大的手机 App 之一,日活跃用户超过3亿,月活跃用户超过11亿(2019年底统计),市场极大. 2017年,微信正式推出了小程序,允许外部开发者在微信内部运行自己的代码,开展业务. ...

  2. mybatis配置入门中遇到的问题

    问题一 非法注射 问题描述:WARNING: An illegal reflective access operation has occurred 这种问题主要是jdk版本和mybatis的jar包 ...

  3. linux中uniq命令全面解析

    目录 一 :uniq作用 二:uniq格式 1.参数 2.参数案例解析: linuxuniq简介 Linux uniq 命令用于检查及删除文本文件中重复出现的行列,一般与 sort 命令结合使用. u ...

  4. super之mro列表牵引出c3算法

    目录 一:super的使用 二:super之mro列表牵引出c3算法 三:mro列表总结使用 一:super的使用 class Person(object): def __init__(self, n ...

  5. 从我做起[AutoMapper实现模块化注册自定义扩展MapTo<>()].Net Core 之二

    AutoMapper实现模块化注册自定义扩展MapTo<>() 我们都知道AutoMapper是使用的最多的实体模型映射,如果没有AutoMapper做对象映射那么我们需要想一下是怎么写的 ...

  6. mac每次打开终端都需要source ~/.bashrc以及~/.bash_profile问题

    问题描述 在学习git的时候在~/.bashrc下面配置了git log命令的别名 #用于输出git提交日志 alias git-log='git log --pretty=oneline --all ...

  7. RabbitMQ简介及安装

    AMQP简介 AMQP AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是进程之间传递异步消息的网络协议. AMQP工作过程 发布者(Publisher ...

  8. Openfeign与Ribbon

    Ribbon和OpenFeign我个人为其实算是两个东西,Ribbon侧重于做服务调用时的负载均衡,而OpenFeign侧重于面向接口进行服务调用. 在只引入Ribbon依赖的时候,可以使用restT ...

  9. js演示面向对象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. idea的jar文件,“java.lang.SecurityException: Invalid signature file digest for Manifest main attribute

    感谢大佬:https://blog.csdn.net/mingyuli/article/details/84674483 命令行运行jar出现问题: 1.找不到主类.打开jar文件包,在MANIFES ...