0

I have a List . Which I've converted to a BindingList and put into a BindingSource and bound to a DataGridView so that I can have the user select which JobItem they want to print. The DataGridView has a ButtonColumn, the user picks the JobItem, clicks the ButtonColumn the JobItem prints to a thermal printer.

My problem is I can’t get the syntax right to pull the selected Business Object off the DataGridView so I can send it to print function.

This is what I’m currently trying:

BusinessObjects.JobItem row = dgJobItems.SelectedRows[e.RowIndex].DataBoundItem;

This is the rest of my code:

DataGridViewButtonColumn btnPrint = new DataGridViewButtonColumn();
btnPrint.Text = "Print";
btnPrint.Name = "bPrint";
btnPrint.UseColumnTextForButtonValue = true;
dgJobItems.Columns.Add(btnPrint);

private void dgJobItems_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        if (dgJobItems.Columns[e.ColumnIndex].Name == "bPrint")
        {
            BusinessObjects.JobItem row = dgJobItems.SelectedRows[e.RowIndex].DataBoundItem;  
        }


    }

JobItem:

public class JobItem
{
    public int jobNumber { get; set; }
    public string serialNumber { get; set; }
    public string modelNumber { get; set; }
    public int quantity { get; set; }
    public string description { get; set; }

    public JobItem()
    {

    }
}

Sorry... I get the following error which I don't understand:

ArgumentOutOfRangeException was unhandled An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

Additional information: Index was out of range. Must be non-negative and less than the size of the collection.

Joe Smith
  • 171
  • 1
  • 3
  • 14
  • No errors? It appears you have the selected row... what is missing? – JohnG Mar 15 '17 at 15:48
  • i have starred this question http://stackoverflow.com/questions/3577297/how-to-handle-click-event-in-button-column-in-datagridview for precisely these cases as i rarely do front end stuff and keep forgetting. This is not an answer to your problem tho. But usually my problem is bind to wrong events. in any case what í'd do is get the object id from that button click and send the corresponding object rather than trusting the data from the front end to print. – Rostol Mar 15 '17 at 15:52
  • @JohnG Sorry... Yes I got an error. I added it. ArgumentOutOfRangeException in a dll called mscorlib. dll. – Joe Smith Mar 15 '17 at 16:02

2 Answers2

1

I am guessing it is the SelectedRows that is not returning what you are expecting. Since it is a single button in a row, use dgJobItems.Rows and the e.rowIndex like below. See if this helps.

if (dgJobItems.Columns[e.ColumnIndex].Name == "bPrint") {
  JobItem jobItem = (JobItem)dgJobItems.Rows[e.RowIndex].DataBoundItem;
  MessageBox.Show("Job Item" + jobItem.ToString());
}
JohnG
  • 9,259
  • 2
  • 20
  • 29
0

I have an extension method I use to get the related business object for the currently selected row.

public static T GetSelectedPOCO<T>(this DataGridView grid) where T : class
{
    return (grid.SelectedRows.Count == 1)
        ? grid.SelectedRows[0].DataBoundItem as T
        : null;
}

Can be called like this:

Customer selectedCustomer = dgvCustomers.GetSelectedPOCO<Customer>();

Btw, this extension assumes multiple rows cannot be selected. May need to alter it if that's not the case for you.

Jaja Harris
  • 4,266
  • 4
  • 23
  • 22