鸡肋还是革新——Blazor进WinForm

DotNetCore实战

共 7068字,需浏览 15分钟

 ·

2021-04-24 21:58


winform是一老技术,感觉都有点掉牙了(我近20年前就是从winform开始接触.net的);blazor,是微软技术圈里的新宠,正在被悉心照顾。当这一老一少的技术碰撞后,会有什么火花?

.net v6.0.0-preview.3,给winform和blazor结合带来了前提。https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/Blazor/BlazorWinForm  是我写的一个简单的demo,在winform窗体中引入blazor。

先看一下长什么样:

是一个简单的用助记码查询药品的例子,输入框查询按钮,table的样式都是Bootstrap5.0的,外层是一个winform的Form窗体。

具体实现,先看项目文件csproj的不一样:Sdk要换成Microsoft.NET.Sdk.Razor,然后是要通过nuget引入这些包。

<Project Sdk="Microsoft.NET.Sdk.Razor">  <PropertyGroup>    <OutputType>WinExe</OutputType>    <TargetFramework>net6.0-windows</TargetFramework>    <UseWindowsForms>true</UseWindowsForms>  </PropertyGroup>  <ItemGroup>    <PackageReference Include="Dapper" Version="2.0.78" />    <PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="6.0.0-preview.3.21201.13" />    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0-preview.3.21201.4" />    <PackageReference Include="Microsoft.NET.Sdk.Razor" Version="5.0.0-preview.8.20414.8" />    <PackageReference Include="System.Data.SqlClient" Version="4.8.2" />  </ItemGroup>  <ItemGroup>    <Content Update="wwwroot\app.css">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </Content>    <Content Update="wwwroot\Query.razor">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </Content>    <Content Update="wwwroot\css\bootstrap.min.css">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </Content>    <Content Update="wwwroot\index.html">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </Content>    <Content Update="wwwroot\js\bootstrap.min.js">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </Content>  </ItemGroup>  <ItemGroup>    <None Update="wwwroot\app.css">      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>    </None>    <None Update="wwwroot\Query.razor">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </None>    <None Update="wwwroot\index.html">      <CopyToOutputDirectory>Always</CopyToOutputDirectory>    </None>  </ItemGroup></Project>

通过csproj也知道,我是添加了wwwroot文件夹,并添加了一些前端文件:

index.html是一个模板页,引入一些css和js

<!DOCTYPE html><html>
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>Blazor app</title> <base href="/" /> <link href="{PROJECT NAME}.styles.css" rel="stylesheet" /> <link href="app.css" rel="stylesheet" /> <link href="css/bootstrap.min.css" rel="stylesheet" /></head>
<body> <div id="app" class="container"></div> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div>
<script src="_framework/blazor.webview.js"></script> <script src="js/bootstrap.min.js"></script></body></html>

css和js就不说了,是前端的文件,重点看query.razor,这里实现了主要业务逻辑,业务数据+UI表现

@using Microsoft.AspNetCore.Components.Web@using Dapper@using System.Data.SqlClient;<div class="row">  <div class="col-1"></div>  <div class="col-10">    <div class="input-group mb-3">      <input type="text" class="form-control" id="zjm" placeholder="请输入助记码" @bind="ZJM" aria-describedby="button-addon2">      <button class="btn btn-outline-secondary" type="button" @onclick="GetGoods" id="button-addon2">查询</button>    </div>  </div>  <div class="col-1"></div></div>@code {  private string ZJM { get; set; }  List<Goods> list = new List<Goods>();  void GetGoods()  {    using (var con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["sqlcon"].ConnectionString))    {      if (string.IsNullOrWhiteSpace(ZJM))      {        list = con.Query<Goods>("select top 30 spid,spmch,shpchd,shpgg from spkfk  ").ToList();      }      else      {        list = con.Query<Goods>("select top 30 spid,spmch,shpchd,shpgg from spkfk where zjm like @zjm ",new  {zjm="%"+ZJM+"%" }).ToList();      }    }  }}<div class="row">  <table class="table table-striped table-hover">    <thead>      <tr class="table-dark">        <th scope="col">编号</th>        <th scope="col">名称</th>        <th scope="col">产地</th>        <th scope="col">规格</th>      </tr>    </thead>    <tbody>      @foreach (var item in list)      {       <tr>          <td>@item.spid</td>          <td>@item.spmch</td>          <td>@item.shpchd</td>          <td>@item.shpgg</td>        </tr>      }  </tbody> </table></div>
怎么引入到form窗体中呢?这里有点像之前的winform中引入一个webview,这里换成了BlazorWebView。
using BlazorWinForm.wwwroot;using Microsoft.AspNetCore.Components.WebView.WindowsForms;using Microsoft.Extensions.DependencyInjection;using System.Windows.Forms;
namespace BlazorWinForm{ public partial class frmMain : Form { public frmMain() { InitializeComponent(); var serviceCollection = new ServiceCollection(); serviceCollection.AddBlazorWebView(); var blazor = new BlazorWebView() { Dock = DockStyle.Fill, HostPage = "wwwroot/index.html", Services = serviceCollection.BuildServiceProvider(), }; blazor.AutoScroll = false; blazor.RootComponents.Add<Query>("#app"); Controls.Add(blazor); } } class Goods { public string spid { get; set; } public string spmch { get; set; } public string shpchd { get; set; } public string shpgg { get; set; } }}

总体下来,这种把winform+c#+html,css,js混合起来编程,即把丰富的前端框架引入进来,让winform表现更加灵活,强大,也不丢失cs架构对当前电脑的控制力(有很多行业是通过exe来对接专有设备的驱动的)。winform的UI之前是通过三方UI控件比如DevExpress来增强的,虽然有WPF,但还是在微软自己画的一个圈圈里转,blazor则是带来了丰富的前端库。另外,与之前winform嵌入webview不一样的是,blazor中的c#,可以方便的和winform来互动,语言相通,直接交流,比如你可以很轻松的在blazor的页里里new一个form出来。

Blazor进winform,是鸡肋还是革新?应该是仁者见仁,智者见智了。


往期精彩回顾




【推荐】.NET Core开发实战视频课程 ★★★

.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

【.NET Core微服务实战-统一身份认证】开篇及目录索引

Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

10个小技巧助您写出高性能的ASP.NET Core代码

用abp vNext快速开发Quartz.NET定时任务管理界面

在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

现身说法:实际业务出发分析百亿数据量下的多表查询优化

关于C#异步编程你应该了解的几点建议

C#异步编程看这篇就够了


浏览 80
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报