日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

prism项目搭建 wpf_Prism完成的一个WPF项目

發布時間:2024/9/15 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 prism项目搭建 wpf_Prism完成的一个WPF项目 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本著每天記錄一點成長一點的原則,打算將目前完成的一個WPF項目相關的技術分享出來,供團隊學習與總結。

總共分三個部分:

基礎篇主要針對C#初學者,鞏固C#常用知識點;

中級篇主要針對WPF布局與MaterialDesign美化設計,在減輕代碼量的情況做出漂亮的應用;

終極篇為框架應用實戰,包含系統分層、MVVM框架Prism安裝與使用、ORM框架EntityFramework Core配置與使用、開源數據庫Postgresql配置與使用。

目錄

前言

此篇主要介紹系統分層模型、如何安裝Prism快速開發模板與MVVM框架使用、如何配置ORM框架Entity Framework Core與使用、以及Postgresql數據庫配置。

系統分層

項目比較簡單,大概分層模型如下:

View雙向綁定ViewModel;

ViewModel調用Service取得DataModel業務數據;

Service通過調用Repository取得Entity數據;

Repository調用Entity Framework Core,自動創建Sql執行并返回Entity對象;

Entity Framework Core通過驅動鏈接數據庫。

如果項目功能或者對接端末比較多,最好擴展成微服務。

MVVM框架之Prism

MVVM(Model–view–viewmodel)是微軟的WPF和Silverlight架構師之一John Gossman于2005年發布的軟件架構模式。目的就是把用戶界面設計與業務邏輯開發分離,方便團隊開發和自動化測試。目前流行的Android開發、Web開發都在使用,具體MVVM的介紹參照個人博客:核心框架MVVM與MVC、MVP的區別(圖文詳解)。

一、無框架的MVVM實現

設計與邏輯分離的基本就是綁定,通過發布者訂閱者模式實現數據更新通知。

1、屬性綁定

默認屬性為單向綁定,如果需要雙向綁定需要實現INotifyPropertyChanged接口。

第一步:一般是建立如下基類。

using System;

using System.ComponentModel;

using System.Runtime.CompilerServices;

namespace MvvmDemo.Common

{

///

/// Viewmodel基類,屬性雙向綁定基礎

///

public class ViewModelBase : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

///

/// 屬性變更通知

///

/// 屬性名

public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")

{

if (PropertyChanged != null)

{

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

}

}

}

第二步:各個ViewModel繼承基類。

public class UserViewModel : ViewModelBase

{

private string _userId;

private string _userName;

///

/// 用戶名

///

public string UserId

{

get

{

return _userId;

}

set

{

_userId = value;

NotifyPropertyChanged();

}

}

///

/// 用戶名

///

public string UserName

{

get

{

return _userName;

}

set

{

_userName = value;

NotifyPropertyChanged();

}

}

}

第三步:Xaml綁定屬性,實現消息通知。

備注:通過IValueConverter可以做一些特殊綁定處理。比如,經典的就是Bool值控制Visibility。

[ValueConversion(typeof(bool), typeof(Visibility))]

public class BoolToVisibiltyConverter : MarkupExtension, IValueConverter

{

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

{

bool flag = false;

if (value is bool)

{

flag = (bool)value;

}

else if (value is bool?)

{

bool? nullable = (bool?)value;

flag = nullable.HasValue ? nullable.Value : false;

}

return (flag ? Visibility.Visible : Visibility.Collapsed);

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

{

return value;

}

public override object ProvideValue(IServiceProvider serviceProvider)

{

return this;

}

}

Xaml綁定:頭部需要引入命名空間。

xmlns:converter="clr-namespace:WpfMvvm.Core.Converters"

Grid.Row="2"

Visibility="{Binding ShowFlg,Converter={converter:BoolToVisibiltyConverter}}"

Command="{Binding AddCmd}"

Content="登錄" />

2、事件綁定

WPF提供了Command事件處理屬性,想利用控件中的Command屬性需要實現了ICommand接口的屬性。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Input;

namespace MvvmDemo.Common

{

public class DelegateCommand: ICommand

{

///

/// 命令

///

private Action _Command;

///

/// 命令可否執行判斷

///

private Func _CanExecute;

///

/// 可執行判斷結束后通知命令執行

///

public event EventHandler CanExecuteChanged;

///

/// 構造函數

///

/// 命令

public DelegateCommand(Action command):this(command,null)

{

}

///

/// 構造函數

///

/// 命令

/// 命令可執行判斷

public DelegateCommand(Action command,Func canexecute)

{

if(command==null)

{

throw new ArgumentException("command");

}

_Command = command;

_CanExecute = canexecute;

}

///

/// 命令執行判斷

///

/// 判斷數據

/// 判定結果(True:可執行,False:不可執行)

public bool CanExecute(object parameter)

{

return _CanExecute == null ? true : _CanExecute((T)parameter);

}

///

/// 執行命令

///

/// 參數

public void Execute(object parameter)

{

_Command((T)parameter);

}

}

}

使用它作為事件屬性的類型就可以了。

///

/// 登陸命令

///

public DelegateCommand LoginCommand => new DelegateCommand(

s =>

{

// todo

},

s => !string.IsNullOrEmpty(s)

);

二、Prism的MVVM實現

至于Prism有很多種理由讓我選擇它,比如:

支持MVVM(Binding、Notification、Command等)、微軟成員維護

支持Unity和DryIoc兩種IOC容器

支持WPF、UWP、Xamarin.Froms開發

封裝界面跳轉

封裝彈出消息框

自帶項目模板與快速開發代碼片段

創建View時自動創建ViewModel

默認自動綁定ViewModel到View

...等等

1、配置Prism

最簡單的方法:安裝Prism Template Pack擴展包。

2、使用Prism

通過Prism項目模板創建項目,目前可以創建WPF(.Net Framework和.Net Core)、UWP、Xamarin.Froms等應用。

以前支持四種容器,現在只支持兩種IOC容器:Unity、DryIoc。

*備注:如果通過Prism模板創建項目時出現以下錯誤:

這是因為Autofac已經不被支持。解決辦法:regedit進入注冊表HKEY_CURRENT_USER\Software\Prism,把SelectedContainer刪除或者改成Unity。

生成的解決方案如下:

亮點:解決方案中自動設置了ViewModel的IOC配置,MainWindow.xaml中ViewModel的綁定也自動設置了。

下面通過建立一個簡單的局部界面跳轉實例,體驗一把Prism的高效率:cmd、propp、vs智能提示。

Prism包提供的代碼片段如下,要好好加以利用:

此次項目還用到了以下特性:

2.1 Region Navigation

局部頁面跳轉:

傳遞對象參數;

跳轉前確認;

自定義如何處理已經顯示過的頁面(覆蓋與否);

通過IRegionNavigationJournal接口可以操作頁面跳轉履歷(返回與前進等)。

如上例所示簡單應用。

第一步:標識顯示位置。

第二步:在App.xaml.cs注冊跳轉頁面。

?View Code

第三步:使用IRegionManager實現跳轉。

// 指定需要顯示的頁面名字與顯示位置的ContentControl的名字

_manager.RequestNavigate("ContentRegion", "PageTwo");

2.2、Modules

如果系統功能比較多最好進行分塊處理,如下面訂單和用戶信息的分塊處理。

App.xaml.cs中統一各個模塊數據。

// ModuleLoader會把各個模塊的IOC依賴注入數據匯總共有管理

protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)

{

moduleCatalog.AddModule();

moduleCatalog.AddModule();

}

各個Module里面還是一樣,使用到的所有Service和Repository都注冊,使用IOC容器進行生命周期管理。

public class OrderModule : IModule

{

public void OnInitialized(IContainerProvider containerProvider)

{

}

public void RegisterTypes(IContainerRegistry containerRegistry)

{

containerRegistry.RegisterForNavigation(PageDefine.Order);

containerRegistry.Register();

}

}

2.3、Dialog Service

自定義消息彈出框,比如警告、錯誤、提示等消息框。

第一步:自定義消息框控件,ViewModel繼承IDialogAware接口并實現:

public class NotificationDialogViewModel : BindableBase, IDialogAware

{

private DelegateCommand _closeDialogCommand;

public DelegateCommand CloseDialogCommand =>

_closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand(CloseDialog));

private string _message;

public string Message

{

get { return _message; }

set { SetProperty(ref _message, value); }

}

private string _title = "Notification";

public string Title

{

get { return _title; }

set { SetProperty(ref _title, value); }

}

public event Action RequestClose;

protected virtual void CloseDialog(string parameter)

{

ButtonResult result = ButtonResult.None;

if (parameter?.ToLower() == "true")

result = ButtonResult.OK;

else if (parameter?.ToLower() == "false")

result = ButtonResult.Cancel;

RaiseRequestClose(new DialogResult(result));

}

public virtual void RaiseRequestClose(IDialogResult dialogResult)

{

RequestClose?.Invoke(dialogResult);

}

public virtual bool CanCloseDialog()

{

return true;

}

public virtual void OnDialogClosed()

{

}

public virtual void OnDialogOpened(IDialogParameters parameters)

{

Message = parameters.GetValue("message");

}

}

第二步:App.xaml.cs中注冊自定義的消息框,從而覆蓋默認的消息框:

public partial class App

{

protected override Window CreateShell()

{

return Container.Resolve();

}

protected override void RegisterTypes(IContainerRegistry containerRegistry)

{

containerRegistry.RegisterDialog();

}

}

第三步:通過IDialogService使用消息框:

private void ShowDialog()

{

var message = "This is a message that should be shown in the dialog.";

//using the dialog service as-is

_dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message={message}"), r =>

{

if (r.Result == ButtonResult.None)

Title = "Result is None";

else if (r.Result == ButtonResult.OK)

Title = "Result is OK";

else if (r.Result == ButtonResult.Cancel)

Title = "Result is Cancel";

else

Title = "I Don't know what you did!?";

});

}

第四步:定義消息框顯示屬性:

Entity Framework Core + Postgresql

EntityFrameworkCore:是對象關系映射(ORM)程序,支持語言集成查詢Linq,是輕量、可擴展、開源跨平臺的數據訪問框架。下一個5.0版本將與.NET 5.0一起發布。EntityFrameworkCore只支持CodeFirst,EntityFramework支持DB First和Code First。之所以選擇EFCore是因為:

支持CodeFirst

支持Linq

雙向映射(linq映射成sql,結果集映射成對象)

速度很快

PostgreSQL:是開源先進的對象-關系型數據庫管理系統(ORDBMS),有些特性甚至連商業數據庫都不具備。支持JSON數據存儲,表之間還可以繼承。

一、配置EFCore與PostgreSQL

1、引入針對PostgreSQL的EFCore包

2、添加DB操作上下文

數據庫鏈接替換為你的鏈接,一般都是放配置文件管理。

添加Users字段,通過EFCore將自動創建Users表。

using System;

using Microsoft.EntityFrameworkCore;

using WpfMccm.Entitys;

namespace WpfMvvm.DataAccess

{

public class UserDbContext : DbContext

{

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

{

optionsBuilder.UseNpgsql("Server=127.0.0.1;Database=HBMCS;Port=5432;User Id=test;Password=test;Ssl Mode=Prefer;",

npgsqlOptionsAction: options =>

{

options.CommandTimeout(60);

options.EnableRetryOnFailure(maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30), errorCodesToAdd: null);

});

}

public DbSet Users { get; set; }

}

}

3、安裝Microsoft.EntityFrameworkCore.Tools工具

CodeFirst必備神器。進入程序包管理器控制臺,輸入以下命名安裝EFCore設計工具:

※必須安裝在啟動項目里面,不然會失敗。

Install-Package Microsoft.EntityFrameworkCore.Tools

4、創建Migration

程序包管理器控制臺,默認項目一定要選擇DB操作上下文的項目,然后執行命令:InitDB是文件區分,可以任意修改。

Add-Migration InitDB

執行成功之后,生成帶InitDB區分的表定義數據文件:

6、生成數據庫腳本(生產階段用,開發階段可跳過)

程序包管理器控制臺,執行如下命令生成SQL腳本文件:

Script-Migration

CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (

"MigrationId" character varying(150) NOT NULL,

"ProductVersion" character varying(32) NOT NULL,

CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId")

);

CREATE TABLE "Users" (

"ID" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,

"Name" text NULL,

"Age" integer NOT NULL,

CONSTRAINT "PK_Users" PRIMARY KEY ("ID")

);

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")

VALUES ('20200413133616_InitDB', '3.1.3');

如果系統已經上線,安全起見則需要使用這個方法生成SQL腳本,手動執行SQL更新數據庫。

7、更新數據庫(開發階段用)

程序包管理器控制臺,執行如下命令將表定義更新到DB(按文件名的時間順順添加):

Update-Database

這樣我們就通過類創建了一個數據庫表Users,同時默認會在__EFMigrationsHistory履歷表添加一條合并記錄。

※如果__EFMigrationsHistory中記錄存在則忽略本次更新。

二、使用DB上下文操作數據庫

1、創建IRepository,DB操作基本接口

public interface IRepository where TEntity : class

{

Task GetAsync(int id);

Task AddAsync(TEntity obj);

}

2、創建UserRepository,User專用的DB操作類

public class UserRepository : IRepository

{

private readonly DbContext _dbContext;

private readonly DbSet _dbSet;

public UserRepository(UserDbContext dbContext)

{

_dbContext = dbContext;

_dbSet = dbContext.Set();

}

public async Task AddAsync(User obj)

{

_dbSet.Add(obj);

return await _dbContext.SaveChangesAsync() > 0;

}

public async Task GetAsync(int id)

{

return await _dbSet.FindAsync(id);

}

}

如果需要進行事務操作,可以使用下面方法:

var tran= _dbContext.Database.BeginTransaction();

tran.Commit();

3、Service層調用UserRepository就可以完成用戶的操作。

總結

此篇量稍微有點多,非常感謝能看到這里。整體來說Prism簡化了應用的設計與架構,EFCore簡化了數據庫操作。

總結

以上是生活随笔為你收集整理的prism项目搭建 wpf_Prism完成的一个WPF项目的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。