2012-02-28 138 views
0

在WPF项目中,我将Polyline控件绑定到类型为PointCollection的DependencyProperty。
点的坐标应来自硬件(它是物理疗法的力量板硬件)。
我在控制台应用程序中编写了一些代码来从端口com读取数据,它的工作原理是正确的。我应该使用的代码在我的WPF应用程序
代码:在WPF应用程序中与COM端口通信

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

在视图模型我必然折线的点集合:

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

} 

现在我不知道我怎么能当更新PointCollection从COM端口读取数据以反映UI中硬件的最新变化。
我看过这样的一些文章: Dependency property getters and setters in multithreaded environment
我不知道如何在我的场景中实现。

+1

我建议不要继承'DependencyObject'。创建一个基本的ViewModel类,它实现'INotifyPropertyChanged类 '而不是'PointCollection Pts'使用'ObservableCollection Pts' – 2012-02-28 22:52:00

+0

@jberger谢谢,我会和如何从Com端口更新ObservableCollection ? – Shahin 2012-02-28 23:59:21

回答

1

问题是,您只能从UI线程更新UI。

当您从SerialPort接收到数据时,您将从线程池的某个线程获取它。 你必须切换线程上下文到UI线程。为此,您可以使用Dispatcher对象。

+0

请你给我一些代码的例子吗? 我不知道什么时候应该从COM读取数据,何时更新我的​​收藏,谢谢。 – Shahin 2012-02-29 00:00:47

0

请注意,SerialPort DataReceived事件处理程序在非UI线程上触发/运行。

private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    // create your points 
    // INVOKE update to Point collection 
} 

在互联网上搜索wpf thread observablecollection产生如何在多线程环境中使用的集合可喜的成果。

你应该不需要知道来从COM读取数据,这就是DataReceived事件的目的。这取决于数据传入的频率和数量。如果它真的很频繁并且有很多数据,那么您可能需要过滤一些数据,并且只显示每N次更新。如果它是小块,而不是那么频繁,那么每次只更新一次。