【问题标题】:Communicate with COM port in a WPF application与 WPF 应用程序中的 COM 端口通信
【发布时间】:2012-02-28 21:42:19
【问题描述】:

在 WPF 项目中,我将折线控件绑定到类型为 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
我不知道如何在我的场景中实现。

【问题讨论】:

  • 我建议不要继承 DependencyObject。创建一个实现 INotifyPropertyChanged 的基本 ViewModel 类,而不是 PointCollection Pts 使用 ObservableCollection<Point> Pts
  • @jberger 谢谢,我会以及如何从 Com 端口更新 ObservableCollection

标签: c# wpf multithreading serial-port dependency-properties


【解决方案1】:

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

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

【讨论】:

  • 你能给我一个例子吗?我不知道什么时候应该从 COM 读取数据,什么时候应该更新我的收藏,谢谢。
【解决方案2】:

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

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

在互联网上搜索 wpf thread observablecollection 会产生关于如何在多线程环境中使用集合的有希望的结果。

您不需要知道何时从 COM 读取数据,这就是 DataReceived 事件的用途。这取决于数据传入的频率和数量。如果它真的很频繁并且数据很多,那么您可能想要过滤其中的一些并仅显示每 N 次更新。如果它是小块并且不是那么频繁,那么每次都更新它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多