有时,为了省事,我们也可以把窗体的控件注入到ServiceCollection中,在razor中订阅事件,这样就省了中间的桥梁,直接用控件当桥梁,下面以一个Button和Timer为例,来展示使用方式。
本例是把Button和Timer注入到ServieCollection,在razor中通过引用注入@inject来使用Button和Timer,然后再在OnInitialized中订阅Button的单击事件和Timer的Tick事件,通过点击按钮,Timer开始工作。业务场景是通过Timer模拟秒采集一次指标,输出到Chart的Line类型的页面上,因为web中很多图形化处理简单,美观,丰富。如果是具体采集指示的设备,sdk具有推送功能的话,可以把订单它的推送事件,采集数据,然后在web中展示。
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>WinFormsBlazor</title><base href="/" /><link href="{PROJECT NAME}.styles.css" rel="stylesheet" /><link href="css/app.css" rel="stylesheet" /><link href="WinFormsBlazor.styles.css" rel="stylesheet" /><link href="css/bootstrap.min.css" rel="stylesheet" />
</head>
<body><div id="app" class="container">Loading...</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><script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script><script>var data = {labels: [2000],datasets: [{data: [500],label: "张三", borderColor: "#ad255d",fill: false},{data: [500],label: "李四",borderColor: "#3e95cd", fill: false}]}var optionsAnimation = {animation: false, lineTension: 0.4,scales: {y: {min: -300,max: 300,}} }var myLineChartfunction createChart() {var ctx = document.getElementById("myChart");myLineChart = new Chart(ctx, {type: 'line',data: data,options: optionsAnimation});}function showLines(data, labels) {this.data.labels = labelsthis.data.datasets[0].data = data[0]this.data.datasets[1].data = data[1]myLineChart.update();}
</script>
</body>
</html>
DemoPage.razor
@using Microsoft.AspNetCore.Components.Web
@inject Button but
@inject System.Windows.Forms.Timer timer
@using Microsoft.JSInterop;
@inject IJSRuntime js<div><h2 id="title">折线图</h2>
</div>
<canvas id="myChart" width="400" height="200"></canvas>
@code {List<int> data1 = new List<int>();List<int> data2 = new List<int>();List<int> labels = new List<int>();int key = 0;protected override void OnInitialized(){base.OnInitialized();but.Click += async (s, e) =>{await js.InvokeAsync<object>("createChart");timer.Enabled = true;};timer.Tick += async (s, e) =>{var random = new Random();data1.Add(random.Next(-100, 100));data2.Add(random.Next(-120, 150));labels.Add(key);key++;var newData1 = data1.Count > 20 ? data1.ToArray()[^20..] : data1.ToArray();var newData2 = data2.Count > 20 ? data2.ToArray()[^20..] : data2.ToArray();var newLabels = labels.Count > 20 ? labels.ToArray()[^20..] : labels.ToArray();data1 = new List<int>(newData1);data2 = new List<int>(newData2);labels = new List<int>(newLabels);await CallJS(new int[][] { newData1, newData2 }, newLabels);};async Task CallJS(int[][] data, int[] labels){await js.InvokeAsync<object>("showLines", data, labels);}}
}
chartForm.cs
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;
namespace WinFormsBlazor03
{public partial class chartForm : Form{public chartForm(){InitializeComponent();timer1.Enabled = false;var services = new ServiceCollection();services.AddWindowsFormsBlazorWebView();services.AddSingleton(this.button1);services.AddSingleton(this.timer1);blazorWebView1.HostPage = "wwwroot\\index.html";blazorWebView1.Services = services.BuildServiceProvider();blazorWebView1.RootComponents.Add<DomePage>("#app");}}
}
.csroj文件
<Project Sdk="Microsoft.NET.Sdk.Razor"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net7.0-windows</TargetFramework><Nullable>enable</Nullable><UseWindowsForms>true</UseWindowsForms><ImplicitUsings>enable</ImplicitUsings></PropertyGroup><ItemGroup><PackageReference Include="microsoft.aspnetcore.components.webview.windowsforms" Version="6.0.300-rc.1.5355" /><PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0-preview.3.22175.4" /><PackageReference Include="microsoft.web.webview2" Version="1.0.1222-prerelease" /></ItemGroup><ItemGroup><Content Update="DomePage.razor"><CopyToOutputDirectory>Always</CopyToOutputDirectory><CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory></Content></ItemGroup>
</Project>
最后看一下结果: