title: How to know the input buffer of the serial port has information, in C#?
body: <p>I am building a program in C# to be used in one of my course at a college to demonstrate how Asynchronous connections work using RS-232 and two computers connected together. My course is not about programming, but data networks, so the connectivity is what I am looking for.</p>
  
  <p><a href="https://i.stack.imgur.com/9qfxl.jpg" rel="nofollow noreferrer">picture 1 - sample layout of GUI using Visual Studio 2015</a></p>
  
  <p>One of the features I want to implement in my program is to show how a Master-slave, simplex connection works (i.e. the program can choose between been a master to send input from the keyboard; or slave to only receive information and print it on a textbox).</p>
  
  <p>What I have already is the capability of initializing the serial port with specific characteristics (baud rate, data bits, stop bits, etc). This features are selected using combo boxes from the GUI, and assigned to the port when the user clicks a button to "open the port".</p>
  
  <p>What I don't know is how to create the "slave" part of the program. My idea of what I could do is, after you choose the program to be "slave", you open the port waiting for some sort of flag or event to trigger when the input buffer has data stored.</p>
  
  <p>I've been reading several forums and I can't find anything similar to what I need. I have, however, tested multiple alternatives that I believed would bring me closer to what I need with little to no result. I come to ask for an idea of what I could be doing wrong, or suggestions on how to tackle this problem. The problematic lines are <strong>bolded</strong> (or 2 stars ( * ) ):</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Windows.Forms;
  using System.IO.Ports;
  
  namespace SerialCommTester
  {
  public partial class frmSerialComm : Form
  {
      static SerialPort _PuertoSerial;
  
      public frmSerialComm()
      {
          InitializeComponent();
          getAvailablePorts();
       }
  
      //---------------------------------my functions--------------------------------------
      void getAvailablePorts()
      {
          string[] ports = SerialPort.GetPortNames();
          cmbPortList.Items.AddRange(ports);
      }
  
      void activatePort()
      {
       //Note that all the combo boxes are named somewhat accordingly to what the information they are meant to display.
          if (cmbPortList.Text != "" &amp;&amp; cmbBaudRate.Text != "" &amp;&amp; cmbParity.Text != "" &amp;&amp; cmbStopBits.Text != "")
          {
              _PuertoSerial.PortName = cmbPortList.Text;
              _PuertoSerial.BaudRate = Convert.ToInt32(cmbBaudRate.Text);
              _PuertoSerial.RtsEnable = true;
              _PuertoSerial.DtrEnable = true;
  
              _PuertoSerial.DataBits = Convert.ToInt32(cmbDataBits.Text);
  
              if (cmbParity.Text == "Even") { _PuertoSerial.Parity = Parity.Even; }
              else if (cmbParity.Text == "Odd") { _PuertoSerial.Parity = Parity.Odd; }
              else if (cmbParity.Text == "Space") { _PuertoSerial.Parity = Parity.Space; }
              else if (cmbParity.Text == "Mark") { _PuertoSerial.Parity = Parity.Mark; }
              else { _PuertoSerial.Parity = Parity.None; }
  
              if (cmbStopBits.Text =="2") { _PuertoSerial.StopBits = StopBits.Two; }
              else if (cmbStopBits.Text == "1.5") { _PuertoSerial.StopBits = StopBits.OnePointFive; }
              else { _PuertoSerial.StopBits = StopBits.One; }
  
              if (cmbHandShake.Text == "Software Flow Control") { _PuertoSerial.Handshake = Handshake.XOnXOff; }
              else if (cmbHandShake.Text == "Hardware Flow Control") { _PuertoSerial.Handshake = Handshake.RequestToSend; }
              else { _PuertoSerial.Handshake = Handshake.None; }
  
              _PuertoSerial.ReadTimeout = 500; 
              _PuertoSerial.WriteTimeout = 500;
  
              _PuertoSerial.Open();
  //in my understanding, this line of code is needed to handle data being received. Does it trigger a flag or something?
              **_PuertoSerial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);**
          }
          else
          {
              txtRecieve.Text = "Input selection missing 1 or more characteristics";
          }
      }
  
      **
   private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
      { 
          SerialPort testing = (SerialPort)sender;
          txtRecieve.AppendText(testing.ReadExisting());  //txtRecieve cannot be reached within this function. It indicates the following error: "An object reference is required for the non-static field, method, or property 'frmSerialComm.txtRecieve'
      }
      **
  
      void enableDisableGUI(bool[] input)
      {
          grpConnection.Enabled = input[0];
          grpCharacteristics.Enabled = input[1];
          btnOpenPort.Enabled = input[2];
          btnClosePort.Enabled = input[3];
          txtSend.Enabled = ((cmbControlMasterSlave.Text == "Slave") ? false : true);
      }
  
      //----------------------------C# objects / functions--------------------------------------
      private void btnOpenPort_Click(object sender, EventArgs e)
      {
          try
          {
              _PuertoSerial = new SerialPort();
              activatePort();
          }
          catch(Exception ex)
          {
              MessageBox.Show(ex.Message, "Message ", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
  
          bool[] format = { false, false, false, true};
          enableDisableGUI(format);
      }
  
      private void btnClosePort_Click(object sender, EventArgs e)
      {
          _PuertoSerial.Close();
          bool[] format = { true, true, true, false};
          enableDisableGUI(format);
      }
  
      private void txtSend_KeyPress(object sender, KeyPressEventArgs e)
      {
         _PuertoSerial.Write(e.KeyChar.ToString()); //this is how I send data through the serial port.
      }
  
      private void btnClearTxts_Click(object sender, EventArgs e)
      {
          txtRecieve.Clear();
          txtSend.Clear();
      }
  
  } //class closes
  } //program closes
  </code></pre>
  
  <p>I am not an experienced programmer, I just want to create something useful for my students. Any constructive criticism will be highly appreciated.</p>