Fork me on GitHub

WinForm混合Blazor(下)

  有时,为了省事,我们也可以把窗体的控件注入到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 myLineChart
        function createChart() {
            var ctx = document.getElementById("myChart");
            myLineChart = new Chart(ctx, {
                type: 'line',
                data: data,
                options: optionsAnimation
            });
        }
        function showLines(data, labels) {
            this.data.labels = labels
            this.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>
  方便的了解相关知识,可以关注微信公众号 

 

 

posted @ 2022-12-04 16:20  桂素伟  阅读(202)  评论(0编辑  收藏  举报