如何在属性更改事件上更新Syncfusion仪表的“NeedlePointer”值?

huangapple go评论75阅读模式
英文:

How to make Syncfusion gauge "NeedlePointer" value update on Property Change Event?

问题

I see that you're working with C# code to read data from a LoRa scanner and update a gauge with the received RSSI values. It seems like you're facing an issue where the gauge value doesn't update as expected.

One possible issue I noticed in your code is that when you're updating the Strength property in the SerialPort_DataReceived method, you are using the MainThread.BeginInvokeOnMainThread to update the UI. However, in the ScannerConn_PropertyChanged method, you are creating a new instance of HistoricalData which won't have any connection to the UI.

To update the gauge value correctly, you should directly set the needlePointer.Value and Number.Text properties inside the ScannerConn_PropertyChanged method without creating a new instance of HistoricalData. Here's how you can modify the ScannerConn_PropertyChanged method:

private void ScannerConn_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(scannerConn.Strength))
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            needlePointer.Value = scannerConn.Strength;
            Number.Text = scannerConn.Strength.ToString();
            Debug.WriteLine("test1 " + needlePointer.Value);
            Debug.WriteLine("test2 " + Number.Text);
        });
    }
}

Also, ensure that the ScannerConn_PropertyChanged method is properly subscribed to the PropertyChanged event of scannerConn.

With these changes, the gauge should update correctly when new RSSI values are received.

英文:

I am reading data from a LoRa scanner utilizing SerialPort that gets among other things, the signal strength (RSSI) that ranges between -10 and -110. I want the gauge to update automatically every time a new RSSI value is read.

I have created a serialPortConn class where I connect to the scanner and read the data using a function named SerialPort_DataReceived:

public void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {  
        try
        {
            while (serialPort.BytesToRead > 0)
            {
                 string DataIn = serialPort.ReadLine();
                 Debug.WriteLine("Data received from the scanner: " + DataIn);

                // Process the received data and extract the fields
                    Network data = ProcessReceivedData(DataIn);

                 MainThread.BeginInvokeOnMainThread(() =>
                    {
                        // Check if the data name is not empty or null
                        if (!string.IsNullOrEmpty(data.Name))
                        {
                            // Find the existing network with the same name, if it exists
                            Network existingNetwork = NetworkNames.FirstOrDefault(network => network.Name == data.Name);

                            if (existingNetwork != null)
                            {
                                // Add the RSSI value to the existing network's RSSIList
                        
                                // NetworkNames.Add(new Network { RSSI = data.RSSI });
                                // strength = data.RSSI;
                                Strength = data.RSSI;
                                existingNetwork.RSSI = data.RSSI;
                                existingNetwork.Name = data.Name;

                                Debug.WriteLine("strength: " + strength);

                            }
                            else
                            {
                                // Create a new network with the name and initialize its RSSIList 
                                NetworkNames.Add(new Network { Name = data.Name, RSSI = data.RSSI });

                                // strength = data.RSSI;
                                Strength = data.RSSI;
                            }

                            // Print the network name and its RSSIList for debugging purposes
                            foreach (Network network in NetworkNames)
                            {
                                Debug.WriteLine("NetworkName: " + network.Name + " " + network.RSSI);
                            }

                        }
                    });
            }
        }
        catch (OperationCanceledException)
        {
            // Handle the cancellation if needed
            Debug.WriteLine("Reading data from the scanner was canceled.");
        }
        catch (Exception ex)
        {
            // Handle other exceptions
            Debug.WriteLine($"Failed to read data from the scanner: {ex.Message}");
        }
        
    }

I am savig the new RSSI value to a strength property defined at the beginning of the SerialPortConn as follow:

public class SerialPortConn : INotifyPropertyChanged
    { 
        //public ObservableCollection<Network> NetworkNames { get; set; }
        private SerialPort serialPort;
        Network networkNames = new Network();
        public ObservableCollection<Network> NetworkNames { get; set; } = new ObservableCollection<Network>();
        private int strength;

        public int Strength
        {
            get { return strength; }
            //get => strength;
            set
            {
                if (strength != value)
                {
                    strength = value;
                    OnPropertyChanged(nameof(Strength));
                    //OnPropertyChanged();
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

In the content page code behind, I am trying to assign the Strength property to the NeedlePointer value as follow:

namespace Scanner_MAUI.Pages;

public partial class HistoricalData : ContentPage, INotifyPropertyChanged
{
    //public ObservableCollection<Network> NetworkNames { get; set; }
    private SerialPortConn scannerConn;
    public HistoricalData()
    {
        InitializeComponent();
        needlePointer.Value = scannerConn.Strength;
        Number.Text = scannerConn.Strength.ToString();
        scannerConn.PropertyChanged += ScannerConn_PropertyChanged;

      //..More Code
    }

    private void ScannerConn_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(scannerConn.Strength))
        {
            //MainThread.BeginInvokeOnMainThread(() =>
            //{
                new HistoricalData();
                needlePointer.Value = scannerConn.Strength;
                Number.Text = scannerConn.Strength.ToString();
                Debug.WriteLine("test1 " +  needlePointer.Value);
                Debug.WriteLine("test2 " + Number.Text);
            //});
        }
    }

But the guage value doesn't change.
Note I did a similar approach for a list that shows Network names by adding in the code behind the following line:
NetworkListView.ItemsSource = scannerConn.NetworkNames;
The difference is that the names are saved in an ObservableCollection. And this shows the new names in the listView while the scan is running.

Finally this is the xaml:

 <Frame Grid.Row="1">
            <Grid>
                <gauge:SfRadialGauge x:Name="radialGauge">
                <!-- more stuff -->
                 <gauge:RadialAxis.Pointers>
                     <gauge:NeedlePointer x:Name="needlePointer"  />
                  </gauge:RadialAxis.Pointers>
                  <gauge:RadialAxis.Annotations>
                  <gauge:GaugeAnnotation x:Name="annotation" DirectionUnit="Angle" DirectionValue="90" PositionFactor="0.5">
                     <gauge:GaugeAnnotation.Content>
                         <Label x:Name="Number" FontSize="25" FontAttributes="Bold" TextColor="Black"/>
                      </gauge:GaugeAnnotation.Content>
                        </gauge:GaugeAnnotation>
                       <!-- more stuff -->

Update!!!!
this is the console out put of the data I get:

strength: -24
15:24:50:061	existingNetwork: device_1_dummy -24
15:24:50:061	NetworkName: device_1_dummy -24
15:24:50:061	NetworkName: device_1_dummy -24
15:24:50:061	NetworkName: device_1_dummy -25
15:24:52:309	Data received from the scanner: message: datastearm, name: b'device_1_dummy', type: LoRaRAW, lat: None, lon: None, rssi: -25, snr: 6.0, time: (2023, 6, 15, 20, 32, 39, 775777, None)

strength: -25
....and so on

The negative number is the RSSI value I am after.
With the dummy data that I am getting there is only one network name however the RSSI value changes all the time. I tried using on click and on Item selected events. With These I only get one RSSI value and it shows on the gauge.
PLEASE NOT I AM A NOOBIE STILL 如何在属性更改事件上更新Syncfusion仪表的“NeedlePointer”值?

答案1

得分: 1

SerialPort_DataReceived 方法中,您正在设置 strength,它是一个私有字段,而不是 Strength,它是一个公共属性。后者会触发一个 PropertyChanged 事件,而前者不会。

英文:

in SerialPort_DataReceived you are setting strength which is a private field, not Strength which is a public property. The latter fires a PropertyChanged event, the former does not

huangapple
  • 本文由 发表于 2023年7月4日 20:21:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76612574.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定