c#将事件的参数从另一个类传递到主类

Posted

技术标签:

【中文标题】c#将事件的参数从另一个类传递到主类【英文标题】:c# Passing parameters on event from another class to main class 【发布时间】:2014-05-07 10:00:22 【问题描述】:

我有一个主 (Form1) 类和一个处理所有串行通信 (ComPort) 的第二类

当通过串行端口(事件)接收到新数据时,我想将其传递给 Form1 并对这些数据进行一些操作。 小例子:根据接收到的数据创建长字符串

Form1.cs

public partial class Form1 : Form  
  
//Creating instance of SerialCommunication.
....
....
string receivedString = ""; //Here I will store all data

public void addNewDataMethod(string newDataFromSerial)
 
  receivedString = receivedString + newDataFromSerial;
  MessageBox.Show(receivedString);

SerialCommunication.cs

public partial class SerialCommunicationPort   
      
      constructor()  
            
       .... //open serial port with the relevant parameters  
       ComPort.DataReceived += new SerialDataReceivedEventHandler(ComPortBufferRead);//Create Handler  
        
     public void ComPortBufferRead(object sender, SerialDataReceivedEventArgs e)  
       
      //create array to store buffer data  
      byte[] inputData = new byte[ComPort.BytesToRead];  
      //read the data from buffer  
      ComPort.Read(inputData, 0, ComPort.BytesToRead);  

    //*****  What should I write here in order to  pass "inputData" to Form1.addNewDataMethod ?


      
  

我尝试了以下方法:

Form1 Form;  
Form1.addNewDataMethod(inputData.ToString());

以上代码会产生错误:use of unassigned local variable "Form"

Form1 Form1 = new Form1(); 
Form1.addNewDataMethod(inputData.ToString());

上面会创建一个新的Form1实例,并且不会包含之前接收到的数据。

有什么建议吗?

【问题讨论】:

【参考方案1】:

SerialCommunication 类中创建一个事件,该事件将在数据到达时引发:

public partial class SerialCommunicationPort   
 
    public event Action<byte[]> DataReceived;

    public void ComPortBufferRead(object sender, SerialDataReceivedEventArgs e)  
           
       byte[] inputData = new byte[ComPort.BytesToRead];  
       ComPort.Read(inputData, 0, ComPort.BytesToRead);  

       if (DataReceived != null)
           DataReceived(inputData);
      

然后在您的表单中订阅此事件。

public partial class Form1 : Form  
  
    SerialCommunication serialCommunication;

    public Form1()
    
        InitializeComponent();
        serialCommunication = new SerialCommunication();
        serialCommunication.DataReceived += SerialCommunication_DataReceived;
     

    private void SerialCommunication_DataReceived(byte[] data)
    
        // get string from byte array 
        // and call addNewDataMethod
    

如果您想遵循 Microsoft 的 WinForms 编码指南,那么您应该使用 EventHandler&lt;DataReceivedEventArgs&gt; 委托而不是 Action&lt;byte[]&gt; 委托,其中 DataReceivedEventArgs 是继承自 EventArgs 的类。

【讨论】:

谢谢,我会试试的。为什么需要“if (DataReceived !=null)”? @orenk 与 VB.NET 不同,当您尝试引发没有处理程序的事件时,C# 将抛出 NullReferenceException,因此您需要在引发之前检查是否有人订阅了事件 请注意,对于 c# 6,可以使用空条件运算符 DataReceived?.Invoke(inputData); 简化此空检查【参考方案2】:

可能最好的方法是使用事件。定义一个事件,该事件将采用一个字符串的 EventArgs 参数。在 Form1 中订阅事件并在您的串行通信类中触发事件,将您想要的字符串传递给 eventargs。

你想要的方式应该也可以,但是像这样:

Form1 Form = new Form1();  
Form.Show(); // to display it...
/// to other stuff...
Form.addNewDataMethod(inputData); // call the method on the INSTANCE which you opened!

类似于方法的使用,你可以在 Form1 中定义一个属性:

private string _myString = "";
public string MyString 
    private get    

set 
    string _myString= value;
   // to with the string what you want


然后类似方法调用使用

Form.MyString = "abc";

希望对您有所帮助!

【讨论】:

这里的问题是当我使用“Form1 Form = new Form1();”时它将创建一个新的空Form1,我将无法访问原始Form1中已经存储的数据(我试过了) 为什么要多次调用 new Form1() ?!?!?使用 Form1 Form = new Form1() 打开一次;并在使用参考(表单)之后。 我首先在表单中填写一些数据和串行参数,然后使用这些参数创建一个 SerialPort 实例。在用户已经输入了一些其他数据之后,我无法使用新创建的 FORM1。 (串口参数除外)。你的建议很好如果我想使用 Form1 方法而不操纵现有数据(可能从不同的类收集)

以上是关于c#将事件的参数从另一个类传递到主类的主要内容,如果未能解决你的问题,请参考以下文章

从一个类传值到主类?

创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它。

创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它。

创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它

创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它。

创建一个Point类,有成员变量x,y,方法getX(),setX(),还有一个构造方 法初始化x和y。创建类主类A来测试它。