ComponentOne Reports for WinForms Designer Edition: Using the C1ReportDesigner Control > Step 8 of 9: Add Code to Create and Remove Reports

Step 8 of 9: Add Code to Create and Remove Reports

To remove reports from the list, use the DeleteReport method. The DeleteReport method simply removes the selected item from the report list, clears the Report property of the designer control, then makes a new selection if the list is not empty.

Add the following code to remove reports using the DeleteReport method:

      Visual Basic

' remove current report from the list

Private Sub DeleteReport()

   ' a report must be selected

   Dim index As Integer = _list.SelectedIndex

   If (index < 0) Then Return

 

   ' remove report from the designer and from the list

   _c1rd.Report = Nothing

   _list.Items.RemoveAt(index)

  

   ' select another report if we can

   If (index > _list.Items.Count – 1) Then

      index = _list.Items.Count - 1

      If (index > - 1) Then

          _list.SelectedIndex = index

      End If

   End If

   ' done

   _dirty = True

   UpdateUI()

End Sub

      C#

// remove current report from the list

private void DeleteReport()

{

       // a report must be selected

       int index = _list.SelectedIndex;

       if (index < 0) return;

 

       // remove report from the designer and from the list

       _c1rd.Report = null;

       _list.Items.RemoveAt(index);

 

       // select another report if we can

       if (index > _list.Items.Count-1)

          index = _list.Items.Count-1;

       if (index > -1)

          _list.SelectedIndex = index;

 

       // done

       _dirty = true;

       UpdateUI();

}

The AddReport method is a little more complex. In the full-fledged report designer, this command invokes a wizard that allows the user to select a data source, grouping options, layout, and style. When implementing your designer, you can use the wizard code as-is or customize it to suit your needs.

Rather than just creating a blank new report, the simple designer prompts the user for an MDB file, selects the first table it can find, then the first five fields, and creates a report based on that.

Add the following code to create reports using the AddReport method:

      Visual Basic

Private Sub NewReport()

   ' select a data source (just mdb files in this sample)

   Dim dlg As New OpenFileDialog()

   dlg.FileName = "*.mdb"

   dlg.Title = "Select report data source"

   If dlg.ShowDialog() <> Windows.Forms.DialogResult.OK Then Return

 

   ' select first table from data source

   Dim connString As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", dlg.FileName)

  

   Dim tableName As String = GetFirstTable(connString)

 

   If tableName.Length = 0 Then

      MessageBox.Show("Failed to retrieve data from the selected source.")

      Return

   End If

  

   ' create new report

   Dim rpt As New C1Report()

   rpt.ReportName = tableName

  

   ' set data source

   rpt.DataSource.ConnectionString = connString

   rpt.DataSource.RecordSource = tableName

  

   ' add a title field

   Dim s As Section = rpt.Sections(SectionTypeEnum.Header)

   s.Visible = True

   s.Height = 600

   Dim f As Field = s.Fields.Add("TitleField", tableName, 0, 0, 4000, 600)

   f.Font.Bold = True

   f.Font.Size = 24

   f.ForeColor = Color.Navy

  

   ' add up to 5 calculated fields

   Dim fieldNames As String() = rpt.DataSource.GetDBFieldList(True)

   Dim cnt As Integer = Math.Min(5, fieldNames.Length)

  

   ' add a page header

   s = rpt.Sections(SectionTypeEnum.PageHeader)

   s.Visible = True

   s.Height = 400

   Dim rc As New Rectangle(0, 0, 1000, s.Height)

 

   Dim i As Integer

   For i = 0 To cnt - 1

      f = s.Fields.Add("TitleField", fieldNames(i), rc)

      f.Font.Bold = True

      rc.Offset(rc.Width, 0)

   Next

  

   ' add detail section

   s = rpt.Sections(SectionTypeEnum.Detail)

   s.Visible = True

   s.Height = 300

   rc = New Rectangle(0, 0, 1000, s.Height)

   For i = 0 To cnt - 1

      f = s.Fields.Add("TitleField", fieldNames(i), rc)

      f.Calculated = True

      rc.Offset(rc.Width, 0)

   Next

  

   ' add new report to the list and select it

   _list.Items.Add(New ReportHolder(rpt))

   _list.SelectedIndex = _list.Items.Count - 1

  

   ' done

   _dirty = True

   UpdateUI()

End Sub

      C#

private void NewReport()

{

       // select a data source (just mdb files in this sample)

       OpenFileDialog dlg = new OpenFileDialog();

       dlg.FileName = "*.mdb";

       dlg.Title = "Select report data source";

       if (dlg.ShowDialog() != DialogResult.OK) return;

 

       // select first table from data source

       string connString =

              string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};",

              dlg.FileName);

       string tableName = GetFirstTable(connString);

       if (tableName == null || tableName.Length == 0)

       {

              MessageBox.Show("Failed to retrieve data from the selected source.");

              return;

       }

 

       // create new report

       C1Report rpt = new C1Report();

       rpt.ReportName = tableName;

 

       // set data source

       rpt.DataSource.ConnectionString = connString;

       rpt.DataSource.RecordSource = tableName;

 

       // add a title field

       Section s = rpt.Sections[SectionTypeEnum.Header];

       s.Visible = true;

       s.Height = 600;

       Field f = s.Fields.Add("TitleField", tableName, 0, 0, 4000, 600);

       f.Font.Bold = true;

       f.Font.Size = 24;

       f.ForeColor = Color.Navy;

 

       // add up to 5 calculated fields

       string[] fieldNames = rpt.DataSource.GetDBFieldList(true);

       int cnt = Math.Min(5, fieldNames.Length);

 

       // add a page header

       s = rpt.Sections[SectionTypeEnum.PageHeader];

       s.Visible = true;

       s.Height = 400;

       Rectangle rc = new Rectangle(0, 0, 1000, (int)s.Height);

       for (int i = 0; i < cnt; i++)

       {

              f = s.Fields.Add("TitleField", fieldNames[i], rc);

              f.Font.Bold = true;

              rc.Offset(rc.Width, 0);

       }

 

       // add detail section

       s = rpt.Sections[SectionTypeEnum.Detail];

       s.Visible = true;

       s.Height = 300;

       rc = new Rectangle(0, 0, 1000, (int)s.Height);

       for (int i = 0; i < cnt; i++)

       {

              f = s.Fields.Add("TitleField", fieldNames[i], rc);

              f.Calculated = true;

              rc.Offset(rc.Width, 0);

       }

 

       // add new report to the list and select it

       _list.Items.Add(new ReportHolder(rpt));

       _list.SelectedIndex = _list.Items.Count-1;

 

       // done

       _dirty = true;

       UpdateUI();

}

The following code uses a helper function GetFirstTable that opens a connection, retrieves the db schema, and returns the name of the first table it finds. Add the following code:

      Visual Basic

Private Function GetFirstTable(connString As String) As String

   Dim conn As New OleDbConnection(connString)

   Try

      ' get schema

      conn.Open()

      Dim dt As DataTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)

      Dim dr As DataRow

      For Each dr In dt.Rows

         ' check the table type

         Dim type As String = dr("TABLE_TYPE").ToString().ToUpper()

         If (type <> "TABLE" AndAlso type <> "VIEW" AndAlso type <> "LINK" Then

             'skip this one

         Else

             ' get the table name

             tableName = dr("TABLE_NAME").ToString()

             Exit For

         End If

      Next

     

      ' done

      conn.Close()

   Catch

   End Try

   ' return the first table we found

   Return tableName

End Function

      C#

private string GetFirstTable(string connString)

{

    string tableName = null;

    OleDbConnection conn = new OleDbConnection(connString);

    try

    {

        // get schema

        conn.Open();

 

        DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

        foreach (DataRow dr in dt.Rows)

        {

            // check the table type

            string type = dr["TABLE_TYPE"].ToString().ToUpper();

            if (type != "TABLE" && type != "VIEW" && type != "LINK")

                continue;

 

            // get the table name

            tableName = dr["TABLE_NAME"].ToString();

                break;

        }

 

        // done

        conn.Close();

    }

    catch {}

 

    // return the first table we found

    return tableName;

}


Send comments about this topic to ComponentOne.
Copyright © ComponentOne LLC. All rights reserved.