Как получить данные из события полученных данных классов в MainWindow для обновления пользовательского интерфейса - PullRequest
0 голосов
/ 08 мая 2019

Я создаю программу, которая читает данные в формате .csv из Arduino, подключенного к 3 различным датчикам.Эти данные считываются из класса Serial и отправляются в класс ParseData, который добавляет данные .csv в список и отправляет их в 3 класса для каждого датчика.(Данные от всех трех датчиков отправляются одновременно из Arduino и анализируются из класса ParseData)

Три класса: Sensor1, Sensor2, Sensor3

DataModels: SensorDataModel1, SensorDataModel2, SensorDataModel3

Я хочу обновить диаграмму в MainWindow.xaml / MainWindow.xaml.cs с данными из трех разных классов в виде линии на графике.Я хочу получить уведомление в MainWindow, что эти три датчика имеют новые данные, а затем обновить график с данными.Я не уверен, должен ли я подписываться на событие для каждого датчика или что-то подобное.

// SerialCommunication.cs - read in data and send to ArduinoDataReceived() method for parsing
private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    try
    {
        SerialPort sp = (SerialPort)sender;
        string serialBuffer = sp.ReadLine();

        // Send the subscriber the data received
        if (DataReceived != null)
        {
            DataReceived?.Invoke(this, new SerialDataReceivedEventArgs()
            {
                dataReceived = serialBuffer
            });
        }
    }
    catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}


// ParseData.cs - subscribed to SerialCommunication.cs event and receives the data string and sends data to each sensors class
private void ArduinoDataReceived(object sender, SerialDataReceivedEventArgs e)
{
    Sensor1 sensor1 = new Sensor1();
    Sensor2 sensor2 = new Sensor2();
    Sensor3 sensor3 = new Sensor3();

    // parse all sensor data from Arduino to a list which holds all three sensors data
    List<string> sensorData = e.ToString().Split(',').ToList();

    // parse list for each sensor and send off to each class to process the data
    sensor1.AddData(sensorData1);
    sensor2.AddData(sensorData2);
    sensor3.AddData(sensorData3);
}


// SensorData1.cs - an example of storing the data and adding it to a List of the Sensors data model
public List<SensorDataModel1> ListSensorData1 = new List<SensorDataModel1>();

public void AddData(List<string> data, long dataLength)
{
    SensorDataModel1 s1 = new SensorDataModel1();

    s1.Add(data[0]);
    s1.Add(data[1]);
    s1.Add(data[2]);

    ListSensorData1.Add(s1);
}

Я ожидаю, что все три класса данных отправят данные обратно в MainWindow, а MainWindow обновит диаграмму этимизначения каждый раз, когда они считываются из последовательного порта.

1 Ответ

1 голос
/ 08 мая 2019

Не зная, как устроена вся ваша архетектура, я могу только предполагать. Скорее всего, я бы сделал в вашей ситуации следующее:

1) попросите ваше главное окно подписаться на SerialDataReceivedEventArgs, чтобы событие вызывалось в коде позади главного окна. Этот вопрос должен стать хорошей отправной точкой, чтобы связать это вместе. Это позволит вам обновить данные из вашего главного окна.

2) Если вы используете модель представления и привязку данных; тогда я бы создал команду или метод, чтобы добавить новые данные датчика в ваши коллекции. В вашей модели представления я бы создал ObservableCollection для каждого датчика, а затем использовал привязку, чтобы прикрепить их к главному окну.

//MainWindow XAML
<Window.DataContext>
    <vm:MainWindowViewModel/>
</Window.DataContext>
<YourControl1 ItemSource={Binding Source=SensorData1}/>
<YourControl2 ItemSource={Binding Source=SensorData2}/>
<YourControl3 ItemSource={Binding Source=SensorData3}/>

3) В своем коде MainWindow (или в XAML, если вы хотите создавать новые события), вы можете вызвать команду или метод ViewModel для обновления данных. Используя имена из ссылки выше:

// inside MainWindow.xaml.cs
private void DisplaySerDataHandler(object sender, SerialDataReceivedEventArgs e)
{
   var newSensorData1;
   //...This is where you set all the new sensor data you received to the variables. 
   var dContext = DataContext as MainWindowViewModel;
   dContext?.SetNewSensorData(newSensorData1, newSensorData2, newSensorData3);
}

4) Внутри MainWindowViewModel.cs вы можете иметь бизнес-логику для изменения ObservableCollections, которая будет обновляться при добавлении и автоматически обновлять элементы пользовательского интерфейса.

//you need an ObservableCollection for each list
public ObservableCollection<sensorType> SensorData1 {get;set;}

//then create the command or method to add the data to their respective Collection
public void SetNewSensorData(sensorType sData1, sensorType sData2, sensorType sData3){

  //...then add the new data (with extra logic as needed)
  SensorData1.add(sData1);
  SensorData2.add(sData2);
  SensorData3.add(sData3);
}

Есть много других элементов, которые можно / нужно сделать. Это был пример того, как можно обновить элементы управления главного окна входящими сериализованными данными. Это зависит от вас, как вы хотите, чтобы все было разработано. Ваш MainWindowViewModel будет реализовывать INotifyPropertyChanged. Я предпочитаю использовать команды, так как я могу затем попытаться удалить код из кода и связать все в XAML, и тогда вся моя логика может содержаться во ViewModel. Это не правильный или неправильный способ сделать это, просто мои предпочтения. Я предпочитаю иметь код, который используется только для конкретного изменения самих элементов Control, а вся остальная бизнес-логика находится во ViewModel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...