Writing Code
 Crystal Reports Forum : Crystal Reports for Visual Studio 2005 and Newer : Writing Code
Message Icon Topic: Selected DataGridView rows as a DataSource Post Reply Post New Topic
Author Message
kensk
Newbie
Newbie
Avatar

Joined: 08 Aug 2007
Online Status: Offline
Posts: 5
Quote kensk Replybullet Topic: Selected DataGridView rows as a DataSource
    Posted: 08 Aug 2007 at 2:20pm
Hello,
 
CR newbie here.
 
I have a C# WinForms application that populates a DataGridView from a DataSet.  The user then selects records in the grid and I want to print the selected records to a report.  I'd like to loop through the grid records, picking out the selected ones, and set these records to a DataSource. 
 
Here's the code I'm envisioning:
 

foreach (DataGridViewRow row in this.dataGridViewResponseRecords.Rows)

{

    DataRowView drv = row.DataBoundItem as DataRowView;

    DataSetResponseRecord.ResponseGetRow responseRec = drv.Row

             as DataSetResponseRecord.ResponseGetRow;

    if ((responseRec != null) && (row.Selected == true))

    {

          // Add responseRec to the DataSource

    }

}

// Then set the DataSource to the report.
 
Any ideas on how to do this?
 
OR
 
Alternatively, the DataGridView has a selected rows collection.  Is there a way to set the selected rows to a DataTable?  e.g.

DataTable dt = new DataTable();

DataGridViewSelectedRowCollection mySelectedRows
                                        = this.dataGridViewResponseRecords.SelectedRows;
 
for (int i = 0; i < mySelectedRows.Count; i++)

{

    dt.Rows.Add(mySelectedRows);

}

// Then set the DataTable as the DataSource
 
I've been experimenting, but with not much success.  I get raised exceptions, probably because I'm not setting up the DataTable columns correctly.
 
Any info you can give would be most appreciated.
 
Thanks,
Ken
IP IP Logged
BrianBischof
Admin Group
Admin Group
Avatar

Joined: 09 Nov 2006
Online Status: Offline
Posts: 2458
Quote BrianBischof Replybullet Posted: 08 Aug 2007 at 3:59pm
I don't know how to answer this. What about copying the datatable to a new object and then deleting the unwanted records from the copy? 
Please support the forum! Tell others by linking to it on your blog or website:<a href="http://www.crystalreportsbook.com/forum/">Crystal Reports Forum</a>
IP IP Logged
kensk
Newbie
Newbie
Avatar

Joined: 08 Aug 2007
Online Status: Offline
Posts: 5
Quote kensk Replybullet Posted: 09 Aug 2007 at 6:21am
Hello Brian,
 
Thank you for getting back to me so quickly.  I'm looking forward to your new XI book.  Your first one has gotten me up to speed quicker than I had imagined.
 
I will certainly try your suggestion and see how that pans out.
 
Is it possible to copy the grid row elements to an array of data structures and then set this collection as the data source?
 
Thanks,
Ken
IP IP Logged
BrianBischof
Admin Group
Admin Group
Avatar

Joined: 09 Nov 2006
Online Status: Offline
Posts: 2458
Quote BrianBischof Replybullet Posted: 09 Aug 2007 at 11:31am
Yes, you can print from using any object that implements the IEnumerator class. So that would include an array of data structures. What I don't know how to do is how to specify which elements of the data structure to print out. I still need to do more research in this area to nail down the details (so I can write about it). To do the copy aspect, this would have to be a manual process that loops through the grid and copies over the specific elements you need. I actually did this in the .NET 2003 book showing how to copy from a DataSet to a DataTable (which is no longer necessary with ADO.NET 2).

I hope you like the XI book as much as the .NET book. I really worked hard to make it the best I that I could.  It's being printed right now and will be available in September! 
Please support the forum! Tell others by linking to it on your blog or website:<a href="http://www.crystalreportsbook.com/forum/">Crystal Reports Forum</a>
IP IP Logged
kensk
Newbie
Newbie
Avatar

Joined: 08 Aug 2007
Online Status: Offline
Posts: 5
Quote kensk Replybullet Posted: 09 Aug 2007 at 2:20pm
Hi Brian,
 
Thanks for your prompt reply.  I'll look into the collection approach as well.
 
Regards,
Ken
IP IP Logged
kensk
Newbie
Newbie
Avatar

Joined: 08 Aug 2007
Online Status: Offline
Posts: 5
Quote kensk Replybullet Posted: 20 Aug 2007 at 12:17pm
Hello,
 
Here are two solutions that work.  The first creates a new table from one of my dataset tables and then imports the gridview rows that the user has selected, into the table.  The returned table is then set as the data source for the report.  I'm using CR XI for .NET 2005 release 2.
 
1st solution
 
        private DataTable GetSelectedRecordsDT()
        {
            DataSetResponseRecord.ResponseGetDataTable dt = new DataSetResponseRecord.ResponseGetDataTable();
 
            try
            {
                if (this.dataSetResponseRecord.ResponseGet.Count > 0)
                {
                    foreach (DataGridViewRow row in this.dataGridViewResponseRecords.Rows)
                    {
                        DataRowView drv = row.DataBoundItem as DataRowView;
                       
                        if ((drv.Row != null) && (row.Selected == true))
                        {
                            // Add record to the DataTable
                            dt.ImportRow(drv.Row);
                        }
                    }
                }
                return dt;
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return dt;
        }
 
In the CR report designer, I opened the database expert, navigated to Project Data-ADO.NET Datasets and chose my DataSetResponseRecord to bind to the report.

 
2nd solution:
 
This solution puts the user selected records from the gridview into an ArrayList collection.  The returned ArrayList is then set as the data source for the report.  CollectionResponseRecords is a simple class which copies the gridview row fields (responseRec.data1, responseRec.data2, etc.) into it's own private data members.
 
        private ArrayList GetSelectedRecordsCollection()
        {
            ArrayList aList = new ArrayList();
            try
            {
                if (this.dataSetResponseRecord.ResponseGet.Count > 0)
                {
                    foreach (DataGridViewRow row in this.dataGridViewResponseRecords.Rows)
                    {
                        DataRowView drv = row.DataBoundItem as DataRowView;
                        DataSetResponseRecord.ResponseGetRow responseRec = drv.Row as DataSetResponseRecord.ResponseGetRow;
                       
                        if ((responseRec != null) && (row.Selected == true))
                        {
                            // Add record to the DataSource
                            aList.Add(new CollectionResponseRecords(responseRec));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return aList;
        }
 
In the CR report designer, I opened the database expert, navigated to Project Data-.NET Objects and chose my CollectionResponseRecords to bind to the report.
 
The caller method for either of the two routines above is shown below.  FormCR is a windows form which holds the crystalReportViewer control.
 
        public void PrintPreview()
        {
            try
            {
                string reportPath = Application.StartupPath + "\\" + "CrystalReport2.rpt";
 
                FormCrystalReport formCR = new FormCrystalReport("Computed Exposure Report");
                formCR.reportPath = reportPath;
                formCR.dataSource = GetSelectedRecordsDT();
               
                // OR 
                // formCR.dataSource = GetSelectedRecordsCollection();
 
                formCR.PrintPreview();
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
 
Here is a fragment of the CollectionResponseRecords class:
 
    public class CollectionResponseRecords
    {
        private DateTime readingDate;
        private string instrumentID;
        private double response1;
        private double response2;
        ...
  
        public CollectionResponseRecords(DataSetResponseRecord.ResponseGetRow rr)
        {
            readingDate = rr.readingDate;
            instrumentID = rr.instrumentID;
 
            response1 = rr.Isresponse1Null() ? double.NaN : rr.response1;
            response2 = rr.Isresponse2Null() ? double.NaN : rr.response2;
            ...
        }
    }
 
Hopefully, this code will help other CR newbies.  A lot of my brain cells were burned getting this far.  Maybe a future version of CR will make it easier to access the DataGridView.
 
Regards,
Ken
 

 
 
 
 
IP IP Logged
Post Reply Post New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum



This page was generated in 0.031 seconds.