雞肋還是革新——Blazor進WinForm


  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,是雞肋還是革新?應該是仁者見仁,智者見智了。

 

  想要更快更方便的了解相關知識,可以關注微信公眾號 
 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM