Help needed with tutorial

PDS8475

Active member
Joined
Jun 25, 2019
Messages
41
Programming Experience
Beginner
Hi I have been trying to work through an old tutorial on printing receipts.
The project has the winforms Form1, frmPrint a class called Receipt.cs and a report called rptReceipt.rdlc

The Receipt class is coded

C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrintReceiptDemo
{
    public class Receipt
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public double Price { get; set; }
        public int Quantity { get; set; }
        public string Total { get { return string.Format("£{0}", Price * Quantity); } }
    }
}

The winform Form1 is coded

C#:
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PrintReceiptDemo
{
    public partial class Form1 : Form
    {
        int order = 1;
        double total = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtProductName.Text) && !string.IsNullOrEmpty(txtPrice.Text))
            {
                //Create a new receipt, then add to binding souce
                Receipt obj = new Receipt() { Id = order++, ProductName = txtProductName.Text, Price = Convert.ToDouble(txtPrice.Text), Quantity = Convert.ToInt32(txtQuantity.Text) };
                total += obj.Price * obj.Quantity;
                receiptBindingSource.Add(obj);
                receiptBindingSource.MoveLast();
                txtProductName.Text = string.Empty;
                txtPrice.Text = string.Empty;
                txtTotal.Text = string.Format("£{0}", total);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txtCash.Text = "0.00";
            //Init empty list
            receiptBindingSource.DataSource = new List<Receipt>();
            
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            //Get current object, then remove from binding source
            Receipt obj = receiptBindingSource.Current as Receipt;
            if (obj != null)
            {
                total -= obj.Price * obj.Quantity;
                txtTotal.Text = string.Format("£{0}", total);
            }
            receiptBindingSource.RemoveCurrent();
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            //Open print form
            using (frmPrint frm = new frmPrint(receiptBindingSource.DataSource as List<Receipt>, string.Format("£{0}", total), string.Format("£{0:0.00}", txtCash.Text), string.Format("£{0:0.00}", Convert.ToDouble(txtCash.Text) - total), DateTime.Now.ToString("dd/MM/yyyy")))
            {
                frm.ShowDialog();
            }
        }
    }
}

Form1.jpg


It has the controls
dataGridView which has the datasource receiptBindingSource
txtProductname
txtQuantity
txtPrice
txtTotal
txtCash
btnAdd
btnRemove
btnPrint

frmPrint is coded

C#:
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PrintReceiptDemo
{
    public partial class frmPrint : Form
    {
        List<Receipt> _list;
        string _total, _cash, _change, _date;
        BindingSource ReceiptBindingSource = new BindingSource();
        //You can pass data by using constructor
        public frmPrint(List<Receipt> dataSource, string total, string cash, string change, string date)
        {
            InitializeComponent();
            _list = dataSource;
            _total = total;
            _cash = cash;
            _change = change;
            _date = date;
            
        }

        private void frmPrint_Load(object sender, EventArgs e)
        {
          
            //Set datasource, parameters to RDLC report
            ReceiptBindingSource.DataSource = _list;
            
            Microsoft.Reporting.WinForms.ReportParameter[] para = new Microsoft.Reporting.WinForms.ReportParameter[]
            {
                 new Microsoft.Reporting.WinForms.ReportParameter("pDate",_date),
                new Microsoft.Reporting.WinForms.ReportParameter("pTotal",_total),
                new Microsoft.Reporting.WinForms.ReportParameter("pCash",_cash),
                new Microsoft.Reporting.WinForms.ReportParameter("pChange",_change)
              
            };
            this.reportViewer.LocalReport.SetParameters(para);
            this.reportViewer.RefreshReport();
        }
    }
}

frmPrint.jpg


frmPrint only has the control
reportViewer
which has the report PrintReceiptDemo.rptReceipt.rdlc selected

Also I had to add the line BindingSource ReceiptBindingSource = new BindingSource();
otherwise ReceiptBindingSource in frmPrint_Load was not recognised.

The report rptReceipt is set out as
report.jpg


its parameters are pDate, pTotal, pCash, pChange
its data source is PrintReceiptDemo
and data set is called ds which points to the receipt class

the form it self is working and I can add or remove items but when I click print the reportviewer says
A data source instance has not been supplied for the data source 'ds'
I can not figure out what is causing this
even putting a break point on frmPrint where the parameters are passed to the report shows the right data. But it seems as if the report doesn't get the parameters.

Thanks in advance for any help
 
When you run your code in the debugger, which line is throwing that error?

Also, a link to the tutorial would probably help us get more context, as well.
 
The tutorial I have been trying to do is


There isn't an exception error. So debugging doesn't show any error. But when frmPrint opens that message is across the report viewer. To me it is as if the parameters are never making it to the report. But I don't know why.
 
There is to much code to oversee to resolve this over a forum, and it is nothing a debugger can't find if you are looking for where your datasources are assigned.
Screenshot_49.jpg

Take the above screenshot for example. In your designer, have you set the data source? I don't see ds anywhere in any of the code you've shown. So I assume you are referencing one you've probably created from within the designer. I'm just guessing, but that's what it looks like. You should typically be using one bindingsource. The one you are using is BindingSource ReceiptBindingSource = new BindingSource(); Why don't you try assign that your datasource instead of the one you have in designer code?

A data source instance has not been supplied for the data source 'ds'
I don't think you've provided all of the entwined code for us to understand this issue. Look for where you haven't assigned the datasource to whatever ds is.

There isn't an exception error. So debugging doesn't show any error. But when frmPrint opens that message is across the report viewer.

The debugger wasn't designed for showing errors. While it will stop when encountering an error, It was actually designed to show you what your code is executing in slow motion, so that you can identify irregularities in your codes logic at your own pace. It's your job as the developer to identify problems within that code when debugging. There is a debugging tutorial in my signature, which I think you could benefit from. In order to ascertain where your issue is, I suggest sniffing at your binding source and report viewer to ensure you've set a data source correctly.

Lets know what you find.
 
The only data source that I can see is on Form1 and is called receiptBindingSource and has the binding source property set as PrintReceiptDemo.Receipt. The project data source is set to Receipt.
frmPrint other than me adding the line "BindingSource ReceiptBindingSource = new BindingSource();" doesn't have any data source. And my original problem was that ReceiptBindingSource wasn't recognised in coding and there is no mention of it anywhere else. Hence why I added the line.

Stepping through the code _list only ever has PrintReceiptDemo.Receipt in positon 0 and the other 3 positions are null.

Your right there isn't an instance of ds in the code so I don't know how the data is supposed to pass to it. But I also don't know how to pass data to it as ds is not recognised in coding. Even copying and pasting the code from the Foxlearn site doesn't have any reference in the code to ds FoxLearn | Windows Forms: Print Receipt using Report Viewer in C#
 
Since I am tight on free time, I am unable to give this my full attention. But I think ds is your class Receipt which at a glance, might be assigned from the .rdlc designer.

The tutorial you posted reports of many problems and the guy in the video doesn't respond to those reports with a fix, especially the one you are troubleshooting.

Just an off-topic remark; but, avoid youtube tutorials, because most of them are terrible. If you want to learn c#, search for book recommendations on these forums instead. There have been plenty of suggestions in the past.

Anyway, I hope you resolve it by debugging, or maybe if someone else can point out something I may be overlooking...
 
Back
Top Bottom