2
votes

I have a System.Windows.Forms.DataGridView to show the objects of my type IECInstance.

I'm building a DataTable and fill the table with my objects and set the DataTable as DataSource of my DataGridView. So my DataGridView is showing my objects correctly.

My problem is now to get the objects when i select the row(s).

My first attempt was to use this:

IECInstance theObjectIWant = dataGridView.SelectedRows[0].DataBoundItem as IECInstance.

But DataBountItem returns a DataRowView. So i found many questions for the issue here on SO and some suggested to use this:

var drv = dataGridView1.SelectedRows[0].DataBoundItem as DataRowView;
var row = drv.Row as DataRow;
var val = row[X] as MyType;

But as far i can see, row[X] is a access to the cell (column), so it does not match to my problem.

When i'm using a List<IECInstances> as DataSource instead of the DataTable, the property DataBoundItem returns the proper object. But actually i don't want to set the DataSource as a List.

To make sure: When i talk about objects i mean my business object of the type IECInstace.

1
What is wrong with dataGridView.SelectedRows[0].Cells[0].Value as IECInstance etc..? Or dataGridView.SelectedCells[0].Value as IECInstanceTaW
I want the object from the row, not just a value from a cell.xoned
But the values in the Cells will be the objects in your Table. And a Row is merely a collection of CellsTaW
So a DataTable can't hold the objects? Just the values? I thought one row is one object. And a cell is just a property from the object.xoned
No, no, the Values are the objects. Don't let the word 'Value' fool you, they are real objects of any data type. nothing to do with value vs reference types..!TaW

1 Answers

4
votes

In my first comments I had assumed that the Objects are in fact contained in the Cells' Values. In that case the Cells show whatever the object class's ToString() methods returns. The name 'Value' is a little misleading here as it can hold any object and has nothing to do with value vs reference types.

But in our chat we have established that you create a DataTable and fill it by Linq'ing the objects' properties into it as strings.

So the DataTable as well as the bound DataGridView contain only strings without any reference back to the objects.

To solve the problem you have to include a reference to the original object instances somehow.

One way is to add a Column to the DataTable to hold the reference, maybe like this:

 dataGridView1.Columns.Add("hIECInstance", typeof(IECInstance ));

and fill it with the object references, either by including it in the Linq result set or by including it in the list of columns of your Add() command or by setting it separately.

To hide the reference you can set the column in the DGV to be invisible..

dataGridView1.Columns["hIECInstance"].Visible = false; 

..and to access the object you cast the Value to your object class:

IECInstance theObject = 
       dataGridView1.SelectedRows[0].Cells["hIECInstance"].Value as IECInstance;

Another way to display object Properties as columns in a DataGridView is to put them into a List<T>, here a List<IECInstance >.

When you do that you can set the DGV's DataSource to this list

In such a solution the row is directly associated with the source object and you can refer to it on the row level like this:

IECInstance theObject = 
            dataGridView1.SelectedRows[0].DataBoundItem as IECInstance;

You may want to insert one or two further levels of dataBinding by including BindingList and/or a BindingSource thus adding functionality to the binding .