Subreport In Reportviewer Table - c#

I want to show a ticket list in report viewer and provide printing feature for each ticket and the whole list and also paging the whole list to 3 , 5 or 7 segments. but I have stuck in the first step :)
I am using subreport in reportviwer in a WindowsFormApplication.
This is my MainReport and SubReport:
This is my code after setting ReportEmbeddedResource :
reportViewer1.LocalReport.DataSources.Clear();
ReportDataSource data = new ReportDataSource("DataSet1", dt);
reportViewer1.LocalReport.DataSources.Add(data);
this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(SubreportProcessingEventHandler);
reportViewer1.RefreshReport();
The code in the SubreportProcessingEventHandler:
int i = 0;
void SubreportProcessingEventHandler(object sender , SubreportProcessingEventArgs e)
{
DataRow dr = dt.Rows[i];
e.DataSources.Add(new ReportDataSource("DataSet1", (object)dr.Table));
i++;
}
Because my report should show two tickets this EventHandler lauches two times.Thus, I stored each row of my table(dt) in a DataRow which is named dr. It seems this EventHandler just uses only the first DataRow content. And the result is repetitive tickets. Here's the output:
Note: I am completely sure about the value in the dr. It has been checked before.
I know I should some how tell the SubReport to use different DataSource for each ticket, but I don't know how to achieve this goal.
Any help would be greatly appreciated.Thank you in advance.

I finally solved this problem by passing parameter from main report to subreport
and I edited my EventHandler like this:
void SubreportProcessingEventHandler(object sender , SubreportProcessingEventArgs e)
{
e.DataSources.Add(new ReportDataSource("DataSet1", dt));
}

Related

Calling textbox information from one form to another

I have 2 forms: The first form has textboxes that display different task names and times spent on each task. The second form has a datagridView. Using:
public void DataTableTest()
{
//Create DataTable
DataTable dt = new DataTable();
//Add Columns
dt.Columns.Add("Task Name", typeof(string));
dt.Columns.Add("Time Worke (HH:mm:ss)", typeof(string));
//Add Rows
dt.Rows.Add();
dataGridView1.DataSource = dt;
}
I am able to get the data table layout the way I want. My issue is, I want to pull the textbox.text from Form1 to populate the [0][0] cell of the data table. Something like:
//Add Rows
dt.Rows.Add();
dt.Rows[0][0] = Form1.tasktextbox1.text;
dataGridView1.DataSource = dt;
But this is not working. I am getting the following from my error list when I try to start the program:
'TaskTracker.Form1.TaskTextBox1' is inaccessible due to its protection level.
Thank you in advance for the assistance. If you have any questions ask, first time posting and new to programming.
The error describes itself: TaskTextBox1 is a private member of Form1 and you cannot call it on another class. Add a property to Form1:
Public string task1text { get { return this.textbox1.text; }}
and then use it on the other form:
dt.Rows[0][0] = Form1.task1text;
I was able to complete this task with:
public static string task1text;
public void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
task1text = TaskTextBox1.Text;
ReportForm RF = new ReportForm();
RF.Show();
}
on form1 and using Roozbeh's suggestion on the second form:
dt.Rows[0][0] = Form1.task1text;
Thank you all for your assistance. Slowly figuring it out! :)

C# 2015 - Gridview selected rows to RDLC report - Per page one row

I am working on C# 2015 windows application.
The basic idea is to get the records from the database and display in to the gridview. And print the selected records of grid view using RDLC report.
See the screenshot below for the basic idea.
Now, my print button code is as below:
private void btnPrint_Click(object sender, EventArgs e)
{
List<customer> lstCustomer = new List<customer>();
foreach (DataGridViewRow row in dgCustomers.SelectedRows)
{
customer c = new customer();
c.id = Convert.ToInt32(row.Cells[dgCustomers.Columns["id"].Index].Value);
c.firstName = row.Cells[dgCustomers.Columns["first_name"].Index].Value.ToString();
c.firstName = row.Cells[dgCustomers.Columns["last_name"].Index].Value.ToString();
lstCustomer.Add(c);
}
frmReport r = new frmReport();
r.Show();
ReportViewer v = r.Controls.Find("reportViewer1", true).FirstOrDefault() as ReportViewer;
v.LocalReport.ReportEmbeddedResource = "bolt.rptBolt.rdlc";
ReportDataSource dataset = new ReportDataSource("ReportDataSet1", lstCustomer);
v.LocalReport.DataSources.Clear();
v.LocalReport.DataSources.Add(dataset);
v.LocalReport.Refresh();
v.RefreshReport();
this.Hide();
}
See, I have created a List lstCustomer of class customer and added objects of the selected rows' cell values into it.
I have created a new form frmReport to display the report and added a reportviewer into it.
I have also taken an Rdlc report named rptBolt.rdlc and added it to the report viewer.
I have set the datasource of report with my list.
But now, I am not sure how to bind id, first name and last name into the report's text boxes.
P.S. I want separate page for each record.
I am not sure how to do it. Can anyone knows?
You can do like this,
In the frmReport, create one property called as ReportId and use as below.
/* Below Code goes to frmReport.cs */
//after the frmReport()
public int ReportId;
//In your forms where u have rdlc
frmReport r = new frmReport();
r.ReportId = GetTheSelectedRecordFromGridView();
r.Show();
ReportViewer v = r.Controls.Find("reportViewer1", true).FirstOrDefault() as ReportViewer;
v.LocalReport.ReportEmbeddedResource = "bolt.rptBolt.rdlc";
//Apply your ReportId to filter the record
//But it is good, to apply this filter to the original database call/query
lstCustomer = lstCustomer.Where(x=>x.Id==ReportId).ToList();
ReportDataSource dataset = new ReportDataSource("ReportDataSet1", lstCustomer);
v.LocalReport.DataSources.Clear();
v.LocalReport.DataSources.Add(dataset);
v.LocalReport.Refresh();
v.RefreshReport();
this.Hide();
private int GetTheSelectedRecordFromGridView()
{
//Write your logic, to get the selected Id;
}
Pass the reportId to frmReport, filter the record from database, build Report dataset with the desired fields, bind with reportviewer and display id, firstname and lastname fields.
Hope you got the logic / idea.

Duplicate columns from MySql db to c#, why?

id pojam opis id pojam opis(duplicate columns)
I am just testing connection from db to c#, and instead of columns id pojam opis I am actually getting id pojam opis id pojam opis in datagridview in c#. Here is part of code which I use to connect database to c#:
public partial class Form1 : Form
{
BindingSource bindingSource1 = new BindingSource();
MySqlConnection conn = new MySqlConnection("Data Source=localhost;database=test;user=root;password=;");
public Form1()
{
this.Load += new System.EventHandler(Form1_Load);
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = bindingSource1;
ubaciPodatke();
}
public void ubaciPodatke()
{
try
{
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM csharp", conn);
DataTable table = new DataTable();
da.Fill(table);
bindingSource1.DataSource = table; dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Is it my mistake, or It has to do something with phpmyadmin: Version information: 4.7.0-rc1. I was thinking it can happen because this version isnt stable yet?
edit: what do You think if I delete this form.resx file
user added rows, would this solve the problem?
Few things:
There is no need to do the data binding in the Load event. You can just do it in the constructor after the InitializeComponent() call. This is irrelevant to your issue.
I don't know what ubaciPodatke means since I don't speak that language, but hopefully it is equivalent of InitializeGrid(). In that case you should put
dataGridView.DataSource = null;
dataGridView.Rows.Clear();
dataGridView.Columns.Clear();
as the first line after try. I do such "clean initialize" since I sometimes design the Grid in designer, for "documentation & visualization" purposes, but do the actual grid from the code. Also, it keeps the InitializeGrid() reusable, to be called from other places.
Also, related to the question in the comments,
Am I reading data from dgv wrong?
You should read the data from the bound DataTable and not directly from the DataGridView when binding.
Solution: I had to comment some lines link1 in form.designer.cs and problem disappeared as shown in this photo link2. I am still curious why this happened as I remember only dragging dgv from toolbox and not adding manually column names.

Refresh button - Refreshing data grid view after inserting, deleting, updating

I'm trying to create a refresh button to automatically refresh the data inside my datagridview after i have finish updating them.
However, my refresh button doesn't seem to work. The data displayed remains the same as the original one. It only gets updated after i manually end my windows app and rebuild it.
Here is my code:
private void button_refresh_Click(object sender, EventArgs e)
{
this.acuzioSecureStore_DatabaseXDataSet.AcceptChanges();
}
Please assist. thanks ^_^
The easiest way to handle this is to use a Binding Source object.
If your loading information into your DataGridView from an Access Database then your most likely storing the Data in a Dataset or DataTable.
Create a Binding Source object, and once you have populated your DataTable/Dataset, set the datasource for your Binding Source to your DataTable. Then set the Datasource from the DataGridView as the Binding Source object.
Doing this ensures that any changes in your datagridview or reflected in the DataTable and vice Versa. If you reload data into your DataTable it will reflect in the Data Grid Automatically.
DataTable dt = new DataTable();
BindingSource bs = new BindingSource();
bs.DataSource = dt;
dataGridView1.DataSource= bs;
All changes will now happen automatically.
Hey the solution above is good but when the above code is executed,the table disappears and is not seen. And if I execute
da.Fill(ds, "p");
dataGridView1.DataSource = ds.Tables["p"];
then whole table is created again.
private void button_refresh_Click(object sender, EventArgs e)
{
SqlConnection con=new SqlConnection(#"");
string query="select * from abc";
SqlCommand cmd=new SqlCommand(query,con);
SqlDataAdapter da=new SqlDataadapter(cmd);
DataTable dt=new DataTable();
da.Fill(dt);
dataGridView1.DataSource=dt;
}
I had a datagridview, bound to a table in an Entity Framework database:
dataGridView1.DataSource = MyDatabase.MyTable;
It would never refresh despite two wasted days.
I solved it with a simple workaround:
private void button_refresh_Click(object sender, EventArgs e) {
dataGridView1.DataSource = MyDatabase.MyTable.Where(i =>(true));
}
This is an ugly workaround, and friend explained me how it works - if I do just dataGridView1.DataSource = database.table, it will cache the table and use the cached data forever. The fact that each time we create a new dummy query, prevents .net from caching it.
Please try this, it worked for me and let me know if you have any better option.
private void button3_Click(object sender, EventArgs e)
{
dataGridView1.Refresh();
}
you Can Bind dataGridView On PageLoad or UserControl Load Event and After chage in grid view Call the Load Event
like
this.ucUsers_Load(null, null); // Windows From C#

Enquiry about reportViewer taking parameters from a form

I'm quite new to using ReportViewer. I have a problem that I do not know how to solve.
I have a Date TextBox and a Location TextBox. My problem is that, when the user keys in the date and location, how do I display the same data in the ReportViewer. Below are some screenshots for better understanding. Any help will be appreciated.
Please let me know if more details are required.
I am assuming you'll add a ShowButton button to your Form. However, you can use TextBox event (e.g. Focus Lost, Text Changed etc) instead of button click event.
private void ShowButton_Click(object sender, EventArgs e)
{
DateTime allocationDate = Convert.ToDateTime(allocDateTextBox.Text);
string locationName = locationTextBox.Text;
//You can create as many datasources matching the name of DataSet in your report
ReportDataSource rds = new ReportDataSource("DataSet1");
rds.Value = getData(String.Format("Select * from myTable where theDate={0} AND Location={1}", allocationDate, locationName));
reportViewer1.LocalReport.DataSources.Clear();
//add as many datasources created above
reportViewer1.LocalReport.DataSources.Add(rds);
reportViewer1.RefreshReport();
}
private DataTable getData(string query)
{
//Select new record from database based on the new query with the new criteria
//return the record as DataTable, DataSet or Collection of object
}

Categories