HTML tables with C#
Written by Herb Fickes   
Monday, 08 March 2010 05:12

This describes how to integrate a WinForm application with a Web application using HTML tables using C#.  his discussion assumes familiarity with Visual Studio and C#.

The applications being integrated are a web page with an HTML table and a custom WinForm written in C# using Visual Studio.

The webpage appears as:

HTML_Table_Example_2

While the WinForm is:

HTML_Table_Example_1

Integrating applications requires the use of adapters which are essentially classes that describe and work with the application being integrated.  The adapters in this case are placed in a single OpenSpan project.

The .Net code in this example is a Windows Form project.  You need to add references to the following assemblies from the Global Assembly Cache (gac):

OpenSpan

OpenSpan.Adapters

OpenSpan.Adapters.Web

OpenSpan.Adapters.Windows

An OpenSpan project is created to contain the information for the HTML web page.  Please read the document “” which describes this in more detail, but the basics of creating this are:

Create a new web page adapter and name it OpenSpanIntegration.  Open OpenSpanIntegration.os and set its StartPage property to http://training.openspan.com/product_list1.html

Press the Start Interrogation button and check the Create Global Page checkbox.

Also change the dropdown selection from Default to HTML Table Designer

HTML_Table_Example_3

Drag the target over the table

The HTML Table designer will now start and you can design the table as described in How to Use the HTML Table Designer.docx.

You then need to add a Project Reference to the .Net project so that it will reference the OpenSpan project.

Next, rebuild the solution.  This is important because we will start using the adapter and controls in the .Net project and we need a project reference that includes those object.

Remember that if you add or remove controls or add/remove adapters, you should rebuild so that the references are also added/removed for any other projects using it.

You can read the attached .Net solution for the full code.  The following explains some of the key points.

A new object is created of type HtmlTable.  This is the OpenSpan adapter you created when interrogating the HTML table in the web page.  From a .Net perspective, it’s just another class.

The class is instantiated, a couple of event handlers are attached to it and then it is started.  The Start() method takes a parameter of this which is the Windows Form.  It is used to synchronize the events from the adapter’s thread, to the Winform’s thread.

OpenSpanIntegration.HtmlTable HtmlTable = null;

private void Form1_Load( object sender, EventArgs e )
{
       HtmlTable = new HtmlTable();

       HtmlTable.ProductList.Created += new EventHandler( ProductList_Created );
       HtmlTable.matchCell_Price.Created += new EventHandler( matchCell_Price_Created );

       // detect when the web page is closed
       HtmlTable.Stopped += new EventHandler( HtmlTable_Stopped );

       HtmlTable.Start( this );
}

 

Stopping Applications

When you run the solution and then stop it from the debugger, you will see that web page is still running.  This is because is a separate application and all the debugger is stopping is the code you’ve written, not other applications.

You can stop the adapters in code and doing so will close the application it is associated with.  In the code sample, we’ve added detecting if the web page is stopped.  If it is, we restart it.

If the WinForm is stopped, then we stop both the WinForm and the web page.

///

Handles if the webpage is closed.
void HtmlTable_Stopped( object sender, EventArgs e )
{
      // Restart the web page so it couldn't be closed until the
      // main application closed.
      HtmlTable.Start( this );
}

private void Form1_FormClosed( object sender, FormClosedEventArgs e )
{
      // If the Form is closed, then also close the browser
      if ( HtmlTable != null && HtmlTable.IsRunning )
      {
            // Don't allow a race condition where the HtmlTable_Stopped event also runs
            HtmlTable.Stopped -= new EventHandler( HtmlTable_Stopped );

            HtmlTable.Stop();
      }
}

When the table is rendered in the browser, OpenSpan matches it to the adapter and fires a Created  event.  In our code we are taking the column headers to fill in the labels for fields in the Winform.  Notice that the code here is like any .Net class, there is no indication that it’s from another application.

void ProductList_Created( object sender, EventArgs e )
{
       // Copy the text of columns of the HTML table to the labels in the form
       this.label1.Text = HtmlTable.matchCell_Product.Text;
       label2.Text = HtmlTable.matchCell_ProductID.Text;
       label3.Text = HtmlTable.matchCell_Price.Text;
}


The Winform application has a textbox for reading information from the HTML table.  You enter a table row and it retrieves the information.  One way to do this is the GetCell()  method shown below.  You could hardcode the column information but its safer to use the Index from the adapter.

private void GetData_Click( object sender, EventArgs e )
{
       try
       {
              int row = Convert.ToInt32( DataInput.Text );

              Product.Text = HtmlTable.Product_Table.GetCell( row, HtmlTable.dataCell_Product.Index ).Text;
              Price.Text = HtmlTable.Product_Table.GetCell( row, HtmlTable.dataCell_Price.Index ).Text;
              ProductID.Text = HtmlTable.Product_Table.GetCell( row, HtmlTable.dataCell_ProductID.Index ).Text;
       }
       catch ( Exception exp )
       {
              MessageBox.Show( "Unable to get data from table.\r\n\r\n" + exp.Message + "\r\n" + exp.StackTrace, "Error" );
       }
}

Finally, the Winform application has a query field where you enter a beverage name and it finds the information.  The example shows using a DataTable to do this.  When OpenSpan matches a HTML table, the adapter formats the information in the table into a .Net DataTable object.  You can then operate upon this like any database table including the use of SQL Select statements.

private void Query_Click( object sender, EventArgs e )
{
       try
       {
              // One way to read data from the HTML table via a DataTable query.
              DataTable table = HtmlTable.tableSection1.GetTable();

              // This uses a SQL select statement to return the requested row.
              DataRow[] rows = table.Select( string.Format( "dataCell_Product='{0}'", QueryInput.Text ) );
              if ( rows != null && rows.Length == 1 )
              {
                     QueryResult1.Text = rows[ 0 ].ItemArray[ HtmlTable.dataCell_Price.Index + 1 ] as string;
                     QueryResult2.Text = rows[ 0 ].ItemArray[ HtmlTable.dataCell_ProductID.Index + 1 ] as string;
              }
              else
              {
                     MessageBox.Show( "No items returned for query.", "Warning" );
              }
       }
       catch ( Exception exp )
       {
              MessageBox.Show( "Query failed.\r\n\r\n" + exp.Message + "\r\n" + exp.StackTrace, "Error" );
       }
}