我有一个单例类 DataPacketAggregator,它从通过 USB 连接的嵌入式设备收集数据包。数据包总是以突发方式接收。每个数据包都包含一个传感器标识和一个源地址(来自 ZigBee 通信)。基本上这就是 DataPacket 类所提供的:
public class DataPacket
{
public String SourceAddress {get; set;}
public Byte SensorID {get; set;}
public DateTime Timestamp {get; set;}
public Int16 Value {get; set;}
}
Aggregator 类提供了这个基本实现:
public class DataPacketAggregator: INotifyPropertyChanged
{
Dictionary<String, ObservableCollection<DataPacket>> _dpkts; //Container
//Method for getting an observable collection containing only values belonging to
//SourceAddress
public ObservableCollection<DataPacket> GetDataBySource(String Source)
{
ObservableCollection<DataPacket> dpkts;
this._dpkts.TryGetValue(Source, out dpkts);
return dpkts;
}
...
}
因此,因为提供给 TableView 的所有值都已经在 ObservableCollection 中,所以 UI 会收到有关 DataPacketAggregator 中发生的任何更改的通知。我已经提供了收集的数据的表格视图,但显示了每个传感器。目前,我将 DataPackets 存储在带有键 SourceAdress 和 DataPacket-Object 值的字典中,其中包含特定于接收到的 DataPacket 的数据。
我现在要做的是为与从用户界面上的 ComboBox 中选择的选定 SourceAddress 关联的每个 Sensor ID 创建一个单线系列图表。LineSeries 应在独立轴上显示时间戳的 DataPacket 数据,在从属轴上显示值。此 ComboBox 的 ItemsSource 属性绑定到提供数据的 Dictionary 中的可用键。关键是并非所有源都需要具有相同数量的与其关联的传感器,我想根据传感器的数量动态重新创建 LineSeries 对象。
我考虑了几种可能的实现:
- 在现有字典中嵌套另一个字典,可以快速访问属于特定传感器的值。问题是,如果您想访问完整的数据集合,则需要再次“合并”数据。
- 使用 LINQ 查询应用分组以获取与特定传感器关联的所有数据。我更喜欢这个解决方案,但这里有两点对我来说。第一:如何在没有重大性能损失的情况下更新 UI(一次又一次地运行所有查询)?如何通知用户界面?因为通常我只想在相关查询有任何变化时通知 UI,但我不能简单地检测到这一点。因此,一旦添加任何 DataPacket(甚至与 UI 绘图无关),我就必须对整个 UI 进行更新和重绘
- 在 DataAggreagtor 中添加一个附加属性,可以设置为当前相关的 SourceAddress(也通过绑定)。我可以返回一个只有 SourceAddress 的 ObservableCollection,我只能查询整个数据的一个子集。此外,可以只更新这个可观察的集合,因为这样就知道要显示哪个 SourceAddress,我可以在不重新查询的情况下更新集合。这样做的主要缺点是我总是被限制在显示来自单一来源的数据。
目前我真的不确定什么是这个问题的最佳解决方案,我也不太熟悉 WPF 工具包图表组件。