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

歡迎訪問 生活随笔!

生活随笔

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

asp.net

DotNetCore 3.0 助力 WPF 开发

發布時間:2023/12/4 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DotNetCore 3.0 助力 WPF 开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

Visual Studio 2019?已經正式發布了,DotNetCore 3.0?的正式版也指日可待。在之前的版本中,作為一名基于微軟生態的傳統?WPF?程序員看著隔壁同學在開發 DotNetCore 網站時用著各種特性好生羨慕,想著巨硬啥時候能讓客戶端開發者也能嘗嘗甜頭。

那么,現在是時候可以嘗試一下了。

需要說明的一點的是,DotNetCore 3.0?雖然跨平臺,但是基于此的 WPF 卻是針對 Windows 特定平臺的實現,并不能跨 Linux 和 MacOS 。

開發環境準備

要想開發?DotNetCore?版本的 WPF,首先需要確保我們的機器上已經安裝了如下

  • Visual Studio 2019?下載地址

需要安裝的組件如下圖所示

  • DotNetCore 3.0 SDK?下載地址

直接默認安裝即可。

全新的開發體驗

在首次使用 VS2019 創建 DotNetCore 版本的 WPF 程序時,VS 可能會給你爆個如下圖所示的錯誤:

按照錯誤提示即可解決該問題,如下圖所示

接著選擇?TOOLS?->?Options,配置如下圖所示

Hello World

首先,我們可以通過 VS 創建一個基于 DotNetCore 的 項目模板,然后我們看一下與傳統的 WPF 項目模板有什么區別。如下圖所示,創建一個 WPF 項目

創建完成后,嘗試編譯編譯運行(注:第一次編譯可能需要較長時間),如下圖所示

如果我們仔細看一下這個新版的項目模板,會發現與傳統的項目模板相比,有好幾處發生了改變:

  • **.csproj 的組織方式發生了改變,與傳統的組織方式相比,內容精簡的快沒有了;

  • 項目默認會引用?Microsoft.NETCore.Platforms?和?Microsoft.WindowsDesktop.App,這兩個 Package 都是針對?WinForm?和?WPF?的特定包

  • 項目屬性中也有一些改動

  • 生成目錄中也有改動,會生成一些以?json?結尾的文件

上述這些改動都是最直觀的改動,但是這些改動貌似不痛不癢,并不能吸引傳統 WPF 開發者投入使用。接觸過?DotNetCore Web?方向的開發者已經對里面的 DI,HttpClientFactory,EFCore 等使用的爐火純青,那我們能不能在 WPF 中也使用這些東西呢?答案是必須要能啊,所有我們還需要探索一下它的一些硬核功能。下面列舉幾個我目前知道的幾個我覺得很炫酷的功能。

使用 DI 和 Service Provider

能夠使用?DI?和?Service Provider,這是我覺得最值得說一下的,因為它的使用方式簡直和在?DotNetCore Web?里面的一摸一樣,值得一說。

首先,我們創建一個 DotNetCore 版本的 WPF 項目,然后引用如下包:

  • Microsoft.Extensions.DependencyInjection

  • Microsoft.Extensions.Options.ConfigurationExtensions

  • Microsoft.Extensions.Configuration.FileExtensions

  • Microsoft.Extensions.Configuration.Json

注:上述包都需要安裝 預覽版本的 3.0.0 版本的才行

然后,在我們的項目根目錄下創建一個?appsettings.json?文件,文件內容如下所示:

{
"AppSettings": {
"StringSetting": "Value",
"IntegerSetting": 42,
"BooleanSetting": true
}
}

然后將該文件的?Build Action?設置為?ContentCopy To Output Directiory?設置為?Copy if newer

接著,我們在項目根目錄下創建一個?AppSettings.cs?文件,用于隱射上面的?appsettings.json?文件,示例代碼如下所示:

public class AppSettings
{
public string StringSetting { get; set; }

public int IntegerSetting { get; set; }

public bool BooleanSetting { get; set; }
}

然后,我們創建一個自定義的接口服務?ISampleService和對應實現?SampleService,示例代碼如下所示:

public interface ISampleService
{
string GetCurrentDate();
}

public class SampleService : ISampleService
{
public string GetCurrentDate() => DateTime.Now.ToLongDateString();
}

然后,修改我們的?App.xaml?文件,刪除掉默認添加的啟動視圖代碼?StartupUri="MainWindow.xaml"

接著,修改我們的?App.xaml.cs?文件,示例代碼如下所示:

public partial class App : Application
{
public IServiceProvider ServiceProvider { get; private set; }

public IConfiguration Configuration { get; private set; }

protected override void OnStartup(StartupEventArgs e)
{
// 初始化配置建造器
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

// 獲取配置建造器創建的對象
Configuration = builder.Build();

//配置全局服務容器
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);

ServiceProvider = serviceCollection.BuildServiceProvider();

var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}

private void ConfigureServices(IServiceCollection services)
{
// 向全局容器中注冊一個視圖
services.AddTransient(typeof(MainWindow));

// 在全局容器中配置 AppSettings
services.Configure<AppSettings>(Configuration.GetSection(nameof(AppSettings)));

// 在全局容器中注冊自定義服務
services.AddScoped<ISampleService, SampleService>();
}
}

修改完畢后,我們可以嘗試編譯我們的項目,如果不出意外的啊,我們的程序會正常啟動起來。這里就不做截圖說明了。

看了上述代碼,是不是覺得很有意思啊,這種全新的開發模式頓時把我們的代碼水平提升了好幾個檔次。這種使用方式和在?AspDotNetCore?簡直一摸一樣。比如,我們在上面注冊了?AppSettings?和一個基于?ISampleService?接口的實現?SampleService,那么我們就可以在?MainWindow?的構造函數中使用,比如,我們可以參考下面的示例代碼:

public partial class MainWindow : Window
{
private readonly ISampleService _sampleService;
private readonly IOptions<AppSettings> _settings;
public MainWindow(ISampleService sampleService, IOptions<AppSettings> settings)
{
InitializeComponent();

_sampleService = sampleService;
var val = _sampleService.GetCurrentDate();

_settings = settings;
}

private void ButtonExit_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}

然后,我們可以監視一下 **_settings** 的值,如下圖所示:

通過這個簡單的例子,我們可以看到這種全新方式的依賴注入已經得到微軟的大力支持,將基于?.NetCore?的?CS模式?和?BS模式?開發方式進行了統一,學習曲線是不是又下降了很多啊。

使用 HttpClientFactory

眾所周知,HttpClient 在實際的使用場景中還是存在一些弊端,在?DotNetCore?的 Web 端中,很多同學用了?HttpClientFactory?如魚得水,減少了很多不必要的麻煩。現在,我們同樣可以將這一利器在 WPF 中使用。

我們新建一個基于?DotNetCore 3.0?的 WPF 項目,然后引入如下包:

  • Microsoft.Extensions.DependencyInjection

  • Microsoft.Extensions.Http

然后,修改我們的?App.xaml?文件,刪除掉默認添加的啟動視圖代碼?StartupUri="MainWindow.xaml",并修改?App.xaml.cs?文件,示例代碼如下所示:

public partial class App : Application
{
public ServiceProvider ServiceProvider { get; private set; }

protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);

ServiceProvider = serviceCollection.BuildServiceProvider();

var mainView = ServiceProvider.GetRequiredService<MainWindow>();
mainView.Show();

base.OnStartup(e);
}

private void ConfigureServices(ServiceCollection services)
{
services.AddHttpClient();
services.AddTransient(typeof(MainWindow));
}
}

最后,修改我們的?MainWindow.xaml.cs?文件,示例代碼如下所示:

public partial class MainWindow : Window
{
private readonly IHttpClientFactory _httpClientFactory;
public MainWindow(IHttpClientFactory httpClientFactory)
{
InitializeComponent();

_httpClientFactory = httpClientFactory;
}

private async void ButtonExit_Click(object sender, RoutedEventArgs e)
{
var client = _httpClientFactory.CreateClient();
var html = await client.GetStringAsync("http://www.baidu.com");
//Application.Current.Shutdown();
}
}

這就是關于?HttpClientFactory?的簡單使用。

使用 EFCore

最后介紹的一大利器就是巨硬的?EFCore,這個東西也很溜,值得我們嘗試使用。這里我使用?Sqlite?為例。

我們新建一個基于?DotNetCore 3.0?的 WPF 項目,然后引入如下包:

  • Microsoft.Extensions.DependencyInjection

  • Microsoft.Extensions.Configuration.FileExtensions

  • Microsoft.Extensions.Configuration.Json

  • Microsoft.EntityFrameworkCore.Sqlite

首先,我們參考上面提到的使用方式,在項目根目錄下創建一個?appsettings.json,文件,修改內容如下所示:

{
"ConnectionStrings": {
"SqlConnection": "datasource = default.sqlite"
}
}

然后將該文件的?Build Action?設置為?ContentCopy To Output Directiory?設置為?Copy if newer

接著,我們創建一個?DataContext?類,示例代碼如下所示:

public class DataContext : DbContext
{
public DataContext(DbContextOptions options) : base(options)
{
this.Database.Migrate();
}
}

然后刪除掉?App.xaml?中的?StartupUri="MainWindow.xaml",并修改?App.xaml.cs,示例代碼如下所示:

public partial class App : Application
{
public ServiceProvider ServiceProvider { get; private set; }
public IConfigurationRoot Configuration { get; private set; }

protected override void OnStartup(StartupEventArgs e)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

Configuration = builder.Build();

var serviceCollection = new ServiceCollection();
ConfigurationServices(serviceCollection);

ServiceProvider = serviceCollection.BuildServiceProvider();
var mainView = ServiceProvider.GetRequiredService<MainWindow>();
mainView.Show();

base.OnStartup(e);
}

private void ConfigurationServices(ServiceCollection services)
{
services.AddTransient(typeof(MainWindow));

services.AddDbContext<DataContext>(options=>options.UseSqlite(Configuration.GetConnectionString("SqlConnection")));
}
}

然后我們修改?MainWindow.xaml.cs,示例代碼如下所示:

public partial class MainWindow : Window
{
private readonly DataContext _dataContext;

public MainWindow(DataContext dataContext)
{
InitializeComponent();

_dataContext = dataContext;
}

private void ButtonExit_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
}

使用方法依然很簡單。

支持 UWP 相關控件 和 Windows10 API

傳統的 WPF 客戶端,如果使用基于 UWP 的相關控件,則可以通過使用?WindowsCommunityToolkit控件庫來使用 UWP 的相關控件,該控件庫目前可能還不是很完善,但是微軟已經在不斷添加新功能了。

UWP?是未來發展的趨勢,但是對于傳統的 WPF,如果想像 UWP 那樣也能使用功能更加強大的 API,只需要通過簡單添加一些引用就可以實現。微軟之前有發布過具體使用的文章,文末有給出鏈接。

發布方式

基于?DotNetCore 3.0?的 WPF 項目發布方式還是和傳統的 WPF 項目發布方式有所差異。全新的發布方式是基于?DotNetCore?的風格來進行設計的。在?Publish?的選項卡中,我們可以看到如下配置

我們可以依據具體情況,來選擇合適的發布方式進行發布。當然,我們也可以借助?Desktop App Converter?工具,將我們的應用分發到 windows Store 上。

總結

通過上述幾個簡單的示例,我們可以看到傳統的 WPF 已經被微軟注入了新鮮的血液,并且在微軟生態下的?C/S端?和?B/S端?開發模式漸趨相同。大大減輕了學習曲線。能夠讓技術在最短的時間里變現,這也是我最看重的地方。

無論是過去還是現在,我都時不時地聽身邊的人說不應該過度依賴工具,但是我想說的是?技術服務于現實,而工具只是為了加速變現,如果一項技術再好再優秀,它卻不能創造現實價值,服務生活,那么我寧愿放棄使用它。微軟為開發者提供了?DotNetCore?的好技術,而?VisualStudio?系列工具作為生產力工具,只是為了提高生產效率。在效率為王的今天,誰贏得了時間,就贏得了一切。

最后,我不打算吹捧?DotNetCoreWPFVisualStudio,以免有人說我會誤導萌新。還是那句話,實踐出真知,感興趣的話可以自己動手嘗試一下。此外,目前?DotNetCore 3.0?還是處于預覽階段,所以可能會有一些坑。但是誰能保證自己第一次就能把事情做的完美呢?時間會證明一切。

補充

評論中很多朋友問到跨平臺的問題,所以我補充了一張圖。

相關參考

  • What's new in .NET Core 3.0 (Preview 2)

  • Around and About .NET World

  • Calling Windows 10 APIs From a Desktop Application

原文地址:https://www.cnblogs.com/hippieZhou/p/10637348.html

.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

總結

以上是生活随笔為你收集整理的DotNetCore 3.0 助力 WPF 开发的全部內容,希望文章能夠幫你解決所遇到的問題。

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