3

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.

xoned
  • 2,701
  • 2
  • 31
  • 43
  • What is wrong with `dataGridView.SelectedRows[0].Cells[0].Value as IECInstance` etc..? Or `dataGridView.SelectedCells[0].Value as IECInstance` – TaW Aug 13 '14 at 09:19
  • I want the object from the row, not just a value from a cell. – xoned Aug 13 '14 at 09:21
  • But the values in the Cells will be the objects in your Table. And a Row is merely a collection of Cells – TaW Aug 13 '14 at 09:24
  • 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 Aug 13 '14 at 09:26
  • 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 Aug 13 '14 at 09:27
  • The DataTable will hold Rows of Columns/Cells. Your objects go into the Cells as their Values. When adressing a single element of a Column we call it Cell. Its values can be anything, a number, a string, a Button, an instance of a class you create, any object.. – TaW Aug 13 '14 at 09:30
  • Thanks for your explanation but i know the main differences between rows/columns/cells. When i talk about objects i mean my business objects (IECInstance). For example my IECInstance has the properties name and location. So in the cells are maybe "Sarah" and "UK", but i don't care about the strings. I want the business object IECInstance when i select the row. Not the values from the cells. – xoned Aug 13 '14 at 09:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/59260/discussion-between-taw-and-timo). – TaW Aug 13 '14 at 09:57

1 Answers1

5

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 .

TaW
  • 53,122
  • 8
  • 69
  • 111