在WPF项目中,我将Polyline控件绑定到具有PointCollection类型的DependencyProperty。
点的坐标应来自硬件(它是理疗力板硬件)。
我在控制台应用程序中编写了一些代码来从端口com读取数据,它可以正常工作。我应该使用我的WPF应用程序中的代码
代码:
public class Hardware
{
private SerialPort _serialPort;
public void TestData()
{
InitSerialPort();
Console.WriteLine("Send data:");
string input = string.Empty;
while (input != "exit")
{
Thread.Sleep(3000);
input = "~";
SendData(input);
}
}
private void SendData(string input)
{
if (!_serialPort.IsOpen)
_serialPort.Open();
_serialPort.Write(input);
Console.WriteLine("data '{0}' has been sent to serial port", input);
}
private void InitSerialPort()
{
_serialPort = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One)
{
Handshake = Handshake.None,
ReadTimeout = 500,
WriteTimeout = 500
};
_serialPort.DataReceived += SerialPortDataReceived;
_serialPort.Open();
return;
}
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(2000);
var buffer = new byte[100];
double deltaV1 = ((buffer[1]*65535 + buffer[2]*255 + buffer[3])*5)/102400;
double X = (25.73*deltaV1) + (-4.27);
double Y = (25.61*deltaV1) + (-3.79);
Console.WriteLine("X: {0}; Y: {1}", X, Y);
}
}
在ViewModel中,我将PolyLine绑定到点集合:
internal class RadarViewModel : DependencyObject, INotifyPropertyChanged
{
public static readonly DependencyProperty PtsProperty =
DependencyProperty.Register("Pts", typeof (PointCollection), typeof (RadarViewModel),
new UIPropertyMetadata(new PointCollection()));
public PointCollection Pts
{
get { return (PointCollection) GetValue(PtsProperty); }
set { SetValue(PtsProperty, value); }
}
public void AddPoint()
{
var rnd = new Random();
Pts.Add(new Point(rnd.Next(90), rnd.Next(90)));
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Pts"));
}
}
现在我不知道如何在从COM端口读取数据时更新PointCollection以反映UI中硬件的最新更改。
我读了一些这样的文章:
Dependency property getters and setters in multithreaded environment
我不知道如何在我的方案中实施。
答案 0 :(得分:1)
问题是,您只能从UI线程更新UI。
当您从SerialPort接收数据时,您将从线程池的某个线程获取它。 您必须将线程上下文切换到UI线程。为此,您可以使用Dispatcher对象。
答案 1 :(得分:0)
请注意,在非UI线程上触发/运行SerialPort DataReceived
事件处理程序。
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
// create your points
// INVOKE update to Point collection
}
互联网搜索wpf thread observablecollection
会产生有关如何在多线程环境中使用集合的有希望的结果。
你不应该知道何时来从COM读取数据,这就是DataReceived
事件的用途。这取决于数据的进入频率和数量。如果它真的很频繁并且有很多数据,那么您可能想要过滤其中的一些数据,并且只显示每N个更新。如果它是小块而不是那么频繁,那么每次都要更新它。