I am new in Blazor and I am trying to create an app reading from a serial port. At first, I created a console application using .Core 3.1 Everything worked fined so I moved the code to Blazor and although when I put debug point I can see that the code works I cannot make the UI to show the value
@using System;
@using System.Diagnostics;
@using System.IO.Ports;
@using System.Threading;
<head>
    <title>Main Scale Monitor</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="/css/all.css" rel="stylesheet">
    <link href="/css/stylesheet.css" rel="stylesheet">
</head>
<div class="scale-monitor">
    <div class="digital-monitor net-weight grid-line">
        <div class="digital-monitor-left net-left">NET</div>
        <div class="digital-monitor-center net-center" bind="@ScaleValue"></div>
        <div class="digital-monitor-right net-right">Kg</div>
    </div>
</div>
@code {
    public string ScaleValue { get; set; } = "0.001";
    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            System.IO.Ports.SerialPort mySerialPort = new System.IO.Ports.SerialPort("COM3");
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = System.IO.Ports.Parity.None;
            mySerialPort.StopBits = System.IO.Ports.StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = System.IO.Ports.Handshake.None;
            mySerialPort.NewLine = (@"&N");
            mySerialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceivedHandler);
            if (!mySerialPort.IsOpen)
            {
                mySerialPort.Open();
            }
        }
    }
    private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        System.IO.Ports.SerialPort sp = (System.IO.Ports.SerialPort)sender;
        try
        {
            string indata = sp.ReadLine();
            ScaleValue = indata.ToString(); //WHEN I PUT DEBUG HERE I CAN SEE THE CORRECT VALUE
        }
        catch (Exception ex)
        {
            string msg = ex.Message;
        }
    }
}
<style>
    *, ::after, ::before {
        box-sizing: unset;
    }
    .grid-line {
        border: 1px solid black;
    }
    .scale-monitor {
        display: grid;
        grid-template-columns: 35% 35% 30%;
        grid-template-rows: 50% 50%;
        width: 100%;
        height: 90%;
        margin: 5px;
        width: 1020px;
    }
    /*#region generic*/
    .digital-monitor {
        background: #000000;
        color: greenyellow;
        text-align: right;
        font-family: digitalregular;
        display: grid;
        grid-template-columns: repeat(10, 1fr);
        grid-template-rows: repeat(5, 1fr);
        width: 95%;
        height: 95%;
        margin: 5px;
        border-radius: 15px;
        align-items: center;
    }
    /*#region generic scalemonitor*/
    .digital-monitor-left {
        writing-mode: vertical-rl;
        opacity: 0.5;
        grid-row: 1 / span 5;
        grid-column: 1;
        text-align: center;
        grid-column: 1;
        transform: rotate(180deg);
    }
    .digital-monitor-center {
        grid-row: 2 / span 3;
        grid-column: 2/ span 7;
        text-align: right;
        vertical-align: bottom;
    }
    .digital-monitor-right {
        grid-row: 2 / span 3;
        grid-column: 9/ span 2;
        text-align: right;
        opacity: 0.75;
        margin-bottom: 0.4em;
        margin-right: 3px;
        align-self: self-end;
    }
    /*#endregion*/
    /*#endregion*/
    /*#region NET*/
    .net-weight {
        grid-column: 2;
        grid-row: 1 / span 2;
        height: 98%;
    }
    .net-left {
        font-size: 40px;
    }
    .net-center {
        font-size: 100px;
    }
    .net-right {
        font-size: 40px;
    }
    /*#endregion NET*/
</style>
Any idea of how I could do the correct binding?
I have found an answer,
I am not 100% this is the best solution
Create a service
public class ReadSerialPortService
{
    public string SerialPortValue { get; set; }
    public ReadSerialPortService()
    {
        System.IO.Ports.SerialPort mySerialPort = new System.IO.Ports.SerialPort("COM3");
        mySerialPort.BaudRate = 9600;
        mySerialPort.Parity = System.IO.Ports.Parity.None;
        mySerialPort.StopBits = System.IO.Ports.StopBits.One;
        mySerialPort.DataBits = 8;
        mySerialPort.Handshake = System.IO.Ports.Handshake.None;
        mySerialPort.NewLine = (@"&N");
        if (!mySerialPort.IsOpen)
        {
            mySerialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(DataReceivedHandler);
            mySerialPort.Open();
        }
    }
    private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        System.IO.Ports.SerialPort sp = (System.IO.Ports.SerialPort)sender;
        double scaleDec = 0.00;
        try
        {
            string indata = sp.ReadLine();
            SerialPortValue = indata.ToString();
        }
        catch (Exception ex)
        {
            string msg = ex.Message;
        }
    }
    public Task<string> GetSerialValue()
    {
        return Task.FromResult(SerialPortValue);
    }
}
And then in the component
@inject ReadSerialPortService _readSerialPortService
<head>
   <title>Main Scale Monitor</title>
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link href="/css/all.css" rel="stylesheet">
   <link href="/css/stylesheet.css" rel="stylesheet">
</head>
<div class="scale-monitor">
   <div class="digital-monitor net-weight grid-line" @onclick="GetValue">
      <div class="digital-monitor-left net-left">NET</div>
      <div class="digital-monitor-center net-center">@ScaleValue</div>
      <div class="digital-monitor-right net-right">Kg</div>
   </div>
</div>
@code {
private int Count { get; set; } = 100;
Timer _updateTimer;
public string ScaleValue { get; set; } = "0.000";    
protected override async Task OnInitializedAsync()
{
    ScaleValue = await _readSerialPortService.GetSerialValue();
    _updateTimer = new Timer(state => { InvokeAsync(GetValue); }, null, 0, 100);
}
public async Task GetValue()
{
    ScaleValue = await _readSerialPortService.GetSerialValue();
    await InvokeAsync(() => StateHasChanged());
}
public void Dispose()
{
    _updateTimer.Dispose();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With