2012-09-27 42 views
-1

我很新的C#,我试图用一个通用串口3种不同的形式:Form2, Form3, Form4在多个表单中使用相同的串行端口实例

Form1.cs并不需要这个,因为它只是需要推出其他形式的节目。基本上,所有3个表单必须同时从同一个串行端口接收数据。我面临的问题是,只有一个表单可以从串口接收数据,但其他两种表单不能。

我发现了一个类似的问题:

Using same serial port data received event on two different forms

类似于雷这个问题?如果是的话,我可以知道应该在哪里将示例代码放在我的代码中的上述链接中?

有人可以帮忙吗?提前致谢!

Form1中:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Form2 f2 = new Form2(); 
     f2.Show(); 
     Form3 f3 = new Form3(); 
     f3.Show(); 
     Form4 f4 = new Form4(); 
     f4.Show(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 
} 

窗体2:

public partial class Form2 : Form 
{ 
    GMapControl MainMap = new GMapControl(); 
    //Initialise data type for latituide and longitude 
    double lat, lng; 
    //Initialise customise marker (plane maker). Declared as m. 
    GMapMarkerImage m = new GMapMarkerImage(new PointLatLng()); 
    GMapOverlay overlayOne; 

    public Form2() 
    { 
     InitializeComponent(); 

     SuspendLayout(); 

     overlayOne = new GMapOverlay(MainMap, "OverlayOne"); 
     MainMap.MapProvider = GMapProviders.YahooMap; 

     MainMap.SetCurrentPositionByKeywords("Singapore"); 
     MainMap.MinZoom = 1; 
     MainMap.MaxZoom = 24; 
     MainMap.Zoom = 13; 
     MainMap.CanDragMap = true; 
     MainMap.DragButton = MouseButtons.Left; 
     MainMap.Dock = DockStyle.Fill; 
     MainMap.Manager.Mode = AccessMode.ServerAndCache; 

     Controls.Add(MainMap); 
     ResumeLayout(true); 


    } 

    public void button1_Click(object sender, EventArgs e) 
    { 
     if (!serialPort1.IsOpen) //if serial port is not open 
      try 
      { 
       serialPort1.Open(); //Open Serial Port 
       if (lat != 0 && lng != 0) //Display marker only when GPS has receive data 
       { 
        overlayOne.Markers.Add(m);   //Add marker on the position given to the overlayOne layer 
        MainMap.Overlays.Add(overlayOne); //Add overlayOne layer to the MainMap layer 
       } 
      } 
      catch 
      { 
       //A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in. 
       MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in."); 
      } 

    } 

    public void button2_Click(object sender, EventArgs e) 
    { 
     if (serialPort1.IsOpen)    // if Serial Port is open 
     { 
      serialPort1.Close();    //Close Serial 
      overlayOne.Markers.Remove(m); 
     } 
    } 

    //When microsoft visual studio receive data 
    public void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
    { 
     this.Invoke(new EventHandler(DoUpdate)); //for function DoUpdate 

     //Pause Microsoft Visual Studio for 100 milliseconds from receiving data, 
     //to ensure serialPort can be close successfully 
     Thread.Sleep(100); 
    } 

    //Function for updating data. Declared as DoUpdate. 
    public void DoUpdate(object sender, EventArgs e) 
    { 
     string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function 

     lat = Convert.ToDouble(c[9]);    //Convert Latitude string data to double data 
     lng = Convert.ToDouble(c[10]);    //Convert Longitude string data to double data 

     //Input lat and lng data in m. 
     //Updating the position of the marker 
     m.Position = new PointLatLng(lat, lng); 

    } 
} 

Form3:

public partial class Form3 : Form 
    { 
     public Form3() 
     { 
      InitializeComponent(); 

     } 

     private void pictureBox1_Click(object sender, EventArgs e) 
     { 
      if (!serialPort1.IsOpen) //if serial port is not open 
       try 
       { 
        serialPort1.Open(); //Open Serial Port 

        //Enable blocks to have colour 
        // ... 
       } 
       catch 
       { 
        //A message box will display this message, informing user either a wrong port has been chosen, or have not been plugged in. 
        MessageBox.Show("There was an error. Please make sure that the correct port was selected, and the device, plugged in."); 
       } 

     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      if (serialPort1.IsOpen)    // if serial port is open 
      { 
       serialPort1.Close();     // Close serial Port 

       //Clear data in textboxes 
       FrontSonar.Text = " "; 
       LeftSonar.Text = " "; 
       RightSonar.Text = " "; 

       //Clear colours in the boxes 
       // ... 
      } 
     } 

     private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) //When microsoft visual studio receive data 
     { 
      this.Invoke(new EventHandler(DoUpdate1)); //To update and ensure sonar data infront of UAV can be displayed without error 
      this.Invoke(new EventHandler(DoUpdate2)); //To update and ensure sonar data left side of UAV can be displayed without error 
      this.Invoke(new EventHandler(DoUpdate3)); //To update and ensure sonar data on the right side of UAV can be displayed without error 

      Thread.Sleep(100); 
     } 

     private void DoUpdate1(object s, EventArgs e) //Display for Sonar infront of UAV 
     { 
      string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function 
      FrontSonar.Text = c[1] + "\n"; 
      double d = Convert.ToDouble(c[1]); 

      if (d > 500) 
      { 
       //Fill blocks with green 
       this.rectangleShape1.FillColor = System.Drawing.Color.Green; 
       this.rectangleShape2.FillColor = System.Drawing.Color.Green; 
       this.rectangleShape3.FillColor = System.Drawing.Color.Green; 
      } 
      else 
       if (d > 400 && d <= 500) 
       { 
        //Fill block with Orange colour 
        this.rectangleShape1.FillColor = System.Drawing.Color.Orange; 
        this.rectangleShape2.FillColor = System.Drawing.Color.Orange; 

        //Fill block with Lavender colour 
        this.rectangleShape3.FillColor = System.Drawing.Color.Lavender; 
       } 
       else 
        if (d <= 400) 
        { 
         //Fill block with red colour 
         this.rectangleShape1.FillColor = System.Drawing.Color.Red; 

         //Fill block with Lavender colour 
         this.rectangleShape2.FillColor = System.Drawing.Color.Lavender; 
         this.rectangleShape3.FillColor = System.Drawing.Color.Lavender; 
        } 

     } 


     private void DoUpdate2(object s, EventArgs e) //Display for Sonar on the left side of UAV 
     { 
      string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function 
      // .... 

     } 

     private void DoUpdate3(object s, EventArgs e) //Display for Sonar on the right side of UAV 
     { 
      string[] c = serialPort1.ReadLine().Split(','); //Stored data seperately by using array & using the Split() function 
      // ... 
     }  
    } 

Form4:(仍在进行中)

public partial class Form4 : Form 
{ 
    public Form4() 
    { 
     InitializeComponent(); 
    } 
} 

回答

1

是的,你可以。下面是实现这一目标的关键点:

  1. 打开串口一次,你的方法if (!port.IsOpened) { port.Open(); }是正确的,在一个静态方法提取这一点,并在每个表单(F2,F3,F4)调用,以避免复制/粘贴这段代码片段。

  2. serialPort变量应该在所有三种形式共享,因此相同的打开和初始化端口实例将是所有形式的访问。考虑到Form1类您提供,创建和初始化代码,开放的端口,然后通过构造函数注入传递的SerialPort的初始化实例为其他形式的类,基本上添加SerialPort port构造函数参数Form2,3,4类,然后:

    // renamed button1_Click 
    private void OnSetup(object sender, EventArgs e) 
    { 
        this.port = new SerialPort(...); 
        // TODO: initialize port 
    
        Form2 f2 = new Form2(this.port); 
        f2.Show(); 
        Form3 f3 = new Form3(this.port); 
        f3.Show(); 
        Form4 f4 = new Form4(this.port); 
        f4.Show(); 
    } 
    
  3. 然后在每个表单构造器中只需订阅serialPort.DataReceived事件,就是这样。

    public Form2(SerialPort port) 
    { 
        port.DataReceived += ... 
    } 
    

一些建议,

  • 给变量和方法,更描述性的名称,而不是form1form2cdbutton2_Click
  • 避免变量幻数,提取常量,给描述性名称,例如有多个出现400,500个神奇的数字,它们是什么都不清楚。
  • 在评论的代码,你说Pause Microsoft Visual Studio...microsoft visual studio receives data...,这是不正确的,你的应用程序的执行(但不是Visual Studio中)将被暂停,同时Thread.Sleep()和你applciation将收到一个进来的串口数据,Visual Studio是只是一个开发环境,在这种情况下不直接涉及港口通信。
+0

嗨,非常感谢您的回复。 1.对不起,但我现在很困惑,因为我在这方面很新颖。通过打开串口一次,你的意思是在Form1中打开一个串口而不是在其他表格中打开串口? 关于静态方法,我只是按照给出的: http://stackoverflow.com/questions/6316544/using-same-serialport-on-two-diferent-forms 并感谢建议和帮助! – user1702497

+0

regaridng端口打开你得到它的权利,当你做'port.Open()' - 变量'端口'引用已经打开的端口,所以只是通过在你的情况下通过构造函数传递其他形式共享此实例。关于所提到的SO帖子,还有另外一种情况 - 在表单中共享数据处理方法,当你想在一个地方处理数据不是不同的时候,这是有意义的,就你而言,据我所知你想要处理每个数据形式以不同的方式,所以你需要不同的事件处理程序为每个表格 – sll

+0

嗨非常感谢答复。抱歉再次打扰你,我们不确定我们应该如何将我们上面提供的链接中的静态类代码放到我们的程序中。你将能够向我们提供一个关于如何将静态类代码放入我们的程序的例子吗?因为我们现在很困惑。并非常感谢你的答复,这真的帮助我们很多!我们非常感谢! :) – user1702497

相关问题