Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从类数据接收事件获取数据到MainWindow以更新UI_C#_Wpf_Xaml_Mvvm_Data Binding - Fatal编程技术网

C# 如何从类数据接收事件获取数据到MainWindow以更新UI

C# 如何从类数据接收事件获取数据到MainWindow以更新UI,c#,wpf,xaml,mvvm,data-binding,C#,Wpf,Xaml,Mvvm,Data Binding,我正在创建一个程序,从连接到3个不同传感器的Arduino读取.csv数据。 该数据从串行类读取并发送到ParseData类,ParseData类将.csv数据添加到列表和 发送给每个传感器的3个类。来自所有三个传感器的数据同时从Arduino发送,并从ParseData类解析 三类:传感器1、传感器2、传感器3 数据模型:SensorDataModel1、SensorDataModel2、SensorDataModel3 我想在MainWindow.xaml/MainWindow.xaml.c

我正在创建一个程序,从连接到3个不同传感器的Arduino读取.csv数据。 该数据从串行类读取并发送到ParseData类,ParseData类将.csv数据添加到列表和 发送给每个传感器的3个类。来自所有三个传感器的数据同时从Arduino发送,并从ParseData类解析

三类:传感器1、传感器2、传感器3

数据模型:SensorDataModel1、SensorDataModel2、SensorDataModel3

我想在MainWindow.xaml/MainWindow.xaml.cs中更新一个图表,将三个不同类的数据作为图表上的一条线。我想在主窗口中得到通知,这三个传感器有新的数据,然后用这些数据更新图表。我不确定是否必须为每个传感器或类似的东西订阅活动

// 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让主窗口订阅SerialDataReceivedEventArgs,以便在主窗口的代码隐藏中引发事件。这应该是一个很好的起点。这将允许您从主窗口更新数据

//MainWindow XAML
<Window.DataContext>
    <vm:MainWindowViewModel/>
</Window.DataContext>
<YourControl1 ItemSource={Binding Source=SensorData1}/>
<YourControl2 ItemSource={Binding Source=SensorData2}/>
<YourControl3 ItemSource={Binding Source=SensorData3}/>
2如果您正在使用viewmodel并绑定数据;然后,我将创建一个命令或方法,将新的传感器数据添加到您的集合中。在viewmodel中,我将为每个传感器创建一个ObservableCollection,然后使用绑定将它们连接到主窗口

//MainWindow XAML
<Window.DataContext>
    <vm:MainWindowViewModel/>
</Window.DataContext>
<YourControl1 ItemSource={Binding Source=SensorData1}/>
<YourControl2 ItemSource={Binding Source=SensorData2}/>
<YourControl3 ItemSource={Binding Source=SensorData3}/>
4在MainWindowViewModel.cs中,您可以使用业务逻辑来更改ObservableCollections,它将在添加到UI元素时更新,并自动更新UI元素

//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);
}

还有许多其他因素可以/应该做。这是关于如何使用传入的序列化数据更新mainwindow控件的示例。这将取决于你想如何设计一切。您的MainWindowViewModel将实现INotifyPropertyChanged。我更喜欢使用命令,因为我可以尝试从代码隐藏中删除代码,并将所有内容绑定到XAML中,然后所有逻辑都可以包含在ViewModel中。这不是一个正确或错误的做法,只是我的喜好。我更喜欢代码隐藏,它只用于专门更改控件元素本身,所有其他业务逻辑都在ViewModel中

您希望主窗口ViewModel或代码隐藏,无论您使用哪一个,都可以拥有每个类的实例并订阅它们的更新/接收方法,然后将其用作重新绘制/向图形添加信息的点。感谢您的评论。我在主窗口中有每个类的一个实例,这三个类都有一个AddData方法来更新一个列表,但我在这些类中没有任何事件要订阅?也许SerialCommunication类中有一些东西?那么我应该改变我的架构吗?在我的parse data类中,订阅了serial receive事件,然后我是否应该通过事件将数据传递给每个传感器类,而不是调用和AddData方法?我认为某种类型的InotifyProperty更改或ObservableCollection可以解决我的问题,但我不太确定如何实施。您的回答的后半部分似乎是一个尝试的好主意。为每个传感器在类上创建3个属性,propfull代码段将有所帮助,然后让类实现INotifyPropertyChanged,每个属性在设置时调用它,这将帮助您了解如何实现它。很抱歉,响应太晚。这是一个很好的答案,对我帮助很大。在看了这篇文章并对MVVM有了更多的了解之后,我已经完全从代码隐藏中删除了我的代码,我目前正在实现命令,谢谢。