e.Item.ItemIndex and e.Item.DataSetIndex

S

Scott M.

When writing the update event handler for a web forms DataGrid, I am running
into a situation that is giving me quite the headache!

If a user has sorted the items in a DataGrid and then chooses to edit one of
the items, I have found that
e.Item.ItemIndex and e.Item.DataSetIndex will both return the same number
even when (in most cases) the item's number in the DataSet is different than
the item's number in the DataGrid.

I supsect that this has something to do with the fact that after a sort, the
grid is bound to a DataView, so when you ask for the e.Item.DataSetIndex,
you are really getting the index in the DataView.

This behavior does not occur when no sort has occured but the user has
changed from one page index to another. In those cases, the
e.Item.ItemIndex will return (correctly) the index of the item in the
DataGrid and e.Item.DataSetIndex will return (correctly) the index of the
item in the DataSet.

What I've had to do to solve the problem when a grid has sorting and paging
turned on is to loop through the DataSet numerically, looking for records
that have the same primary key value in the DataSet as the one being edited.
This works, but there must be a better (more effieicent) way.

Has anyone else run into this? What do you suggest? Why doesn't
"e.Item.DataSetIndex" always produce the value it implies it produces?

Thanks!
 
S

Steven Cheng[MSFT]

Hi Scott,

Thanks for your posting. As for the problem you mentioned, yes, just as
you've mentioed, the DateSetIndex is the index of the DataSource binded to
the DataGrid. And generally , when we bound a dataset or datatable onto a
datagrid, the actual datasource (the datagrid binded with ) is a DataView,
for DataTable, it's the DataTable's DefaultView , for DataSet, it'll be
the DataSet's first table's defaultView if we don't specify a certain table
in the dataset. That's why the e.Item.DateSetIndex is not the value of the
index in DataSet.

Also, as for the following things :
========================
What I've had to do to solve the problem when a grid has sorting and paging
turned on is to loop through the DataSet numerically, looking for records
that have the same primary key value in the DataSet as the one being
edited.
This works, but there must be a better (more effieicent) way.
=========================

I think use PK to find the correct record is reasonable, and we don't need
to loopthrough all the records in DataSet(in fact DataTable), the DataTable
has a "Select" method which can help select DataRows via a simple SQL query
string. For example:

DataRow[] rows = ds.Tables[0].Select("Name = 'David'");

#DataTable.Select Method (String)
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDataDataTableC
lassSelectTopic2.asp?frame=true

Though this query engine is very simple, it'll be much better than we
manually loop through all the rows.

Hope helps. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Scott M.

See inline:

Steven Cheng said:
Hi Scott,

Thanks for your posting. As for the problem you mentioned, yes, just as
you've mentioed, the DateSetIndex is the index of the DataSource binded to
the DataGrid. And generally , when we bound a dataset or datatable onto a
datagrid, the actual datasource (the datagrid binded with ) is a DataView,
for DataTable, it's the DataTable's DefaultView , for DataSet, it'll be
the DataSet's first table's defaultView if we don't specify a certain
table
in the dataset. That's why the e.Item.DateSetIndex is not the value of
the
index in DataSet.

As I stated in my OP, I've noticed that if no sort has been done (and
therefore the DefaultView of the table in the DataSet that my DataGrid is
bound to is being used), then DataSetIndex returns the correct, well,
DataSet index value. Only when a sort has been done and the DataGrid is
bound to a DataView does the DataSetIndex return the wrong number.

So, I guess my question should be stated another way: What is the best way
to retrieve the index of a row in the DataSet from a row in a sorted
DataView? I understand that what you have below is better than my looping
approach, but is what you have below the best way?

Thanks!
Also, as for the following things :
========================
What I've had to do to solve the problem when a grid has sorting and
paging
turned on is to loop through the DataSet numerically, looking for records
that have the same primary key value in the DataSet as the one being
edited.
This works, but there must be a better (more effieicent) way.
=========================

I think use PK to find the correct record is reasonable, and we don't need
to loopthrough all the records in DataSet(in fact DataTable), the
DataTable
has a "Select" method which can help select DataRows via a simple SQL
query
string. For example:

DataRow[] rows = ds.Tables[0].Select("Name = 'David'");

#DataTable.Select Method (String)
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDataDataTableC
lassSelectTopic2.asp?frame=true

Though this query engine is very simple, it'll be much better than we
manually loop through all the rows.

Hope helps. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi Scott,

Thanks for the followup. As for the DataSetIndex, I'm afraid it can only
reference to the directly binded datasource(DataView) rather than the
DataSet(DataTable). In fact, when do sorting, a new DataView(sorted) is
generated from the DataTable(in DataSet) and then they have no
relation(index reference with each other 's record). And if we do need to
reference the raw index in the DataTable, I think we may need to add an
additional column in the DataTable(which contains the index value of each
row in the DataTable). Also, this columns' value need to be bind onto the
DataGrid, when we need to reference the record's index in
DataTable(DataSet) , we read the certain binded value in the DataGrid. I
think it'll improve the speed but cost more space(both memory and the
page's viewstate).
Just some of my thought, if you have any other ideas , please feel free to
post here. Thanks.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Scott M.

Thanks Steven.

I think the better approach is to use the SELECT method that you mentioned
earlier. This will not require adjustments to the original data (adding a
column to serve as a row index is what the PK can do already anyway) and it
won't require looping thought the dataset.

Thanks again.
 
S

Steven Cheng[MSFT]

Thanks for your followup, Scott.

I'm glad that my suggestion is of assistance. Have a good day!


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
T

TheMan

Hello Steven,

I do not understand your solution. I have been struggling to sync my
ItemIndex also, so that after sorting my dataview, the source of my datagrid,
I can edit and delete row items.

In trying to understand your solution I do not see how creating the DataRow
array provides me the ability to return the datagrid the item index. I am
simply lost at that point.

For example, the simple code I want to write in the raised event for the
edit command is,

DataGrid1.EditItemIndex = e.Item.ItemIndex;

But, as I have said, the index is off after sorting. I tried using the
following code

DataGrid1.EditItemIndex = e.Item.Cells[11].Text;

to obtain the PK from the dataset bound in the 12th column, but the text is
string. I cannot convert it to Int because it is a GUID generated in the
database.

Is there a way to obtain the datagrid index property, not the GUID in my
database which is the PK, and pass it to my datagrid as the item in question
for editing?

Thanks.
 
S

Steven Cheng[MSFT]

Hi TheMan,

Thanks for your input.

Yes, if the binded data(dataview) is sorted, the e.Item.ItemIndex has no
effect on the underlying datasource. It is only used to retrieve value from
the DataGrid's DateGridItem's Cell.

In addition, as for the GUID string you mentioned, the DateTable.Select
method doesn't support Guid column's comparasion. However, we can use the
Guid class's constructor to reconstruct the GUID from string . Then, use
the DataTable.Rows.Find method to search DataRow. The Find method can
accept an object or object[] paramter which should be the PK of the
datatable.

HTH. Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top