2012-02-28 129 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次更新。如果它是小塊,而不是那麼頻繁,那麼每次只更新一次。