I am noticing a strange thing with radgridview in CurrentRowChanging event. I have a radgridview without hierarchy, having add new row position at top. The datasource is a dataset and datamember is a datatable.
In current row changing, the following code gives the values for new row just input by using the maximum index, but in another radgridview I get the values by using the index as 0. These 2 codes are as below. Both use the same version of radgridview i.e. Q1 2008 SP1. Can someone please help to explain why this is happening? I would have always expected that behind-the-scenes, a new row ( with rowstate of Added) is being added to a datatable at end of its rows collection, when the CurrentRowChanging event fires.
Thanks
Sunil
CODE 1:
CODE 2:
In current row changing, the following code gives the values for new row just input by using the maximum index, but in another radgridview I get the values by using the index as 0. These 2 codes are as below. Both use the same version of radgridview i.e. Q1 2008 SP1. Can someone please help to explain why this is happening? I would have always expected that behind-the-scenes, a new row ( with rowstate of Added) is being added to a datatable at end of its rows collection, when the CurrentRowChanging event fires.
Thanks
Sunil
CODE 1:
if (e.CurrentRow is GridViewNewRowInfo && this.DataSource != null)
{
DataRowView dataRowView = null;
if (this.Rows.Count >= 1)
{
dataRowView = this.Rows[0].DataBoundItem as DataRowView;
}
}
CODE 2:
if (e.CurrentRow is GridViewNewRowInfo && attributesRadGridView.DataSource != null)
{
DataRowView dataRowView = null;
if (attributesRadGridView.Rows.Count >= 1)
{
dataRowView = attributesRadGridView.Rows[attributesRadGridView.Rows.Count - 1].DataBoundItem as DataRowView;
}
}
33 Answers, 1 is accepted
0
Richard Slade
Top achievements
Rank 2
answered on 16 Oct 2010, 06:45 PM
Hi
I don't have the older version that you have to try this with, but the code below suggests that the dataRowView that is being set:
dataRowView =
this
.Rows[0].DataBoundItem
as
DataRowView;
dataRowView = attributesRadGridView.Rows[attributesRadGridView.Rows.Count - 1].DataBoundItem
as
DataRowView;
i have tried this (with an object datasource and in VB) and it showed me the information from the row at the index given, not the new row which is what I would expect.
I'd also expect in that version to be using the RowsChanged event (you are using the CurrentRowChanging event).
have a look at this forum post
Hope that helps
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 16 Oct 2010, 08:04 PM
Hi Richard,
The reason why I am saying that the datarow corresponds to new row being input is because when I step through the code, I find the values that I just input in new row to be exactly the values I find in the datarow at the mentioned index, and also the dataRowView.IsNew property is always true for the mentioned index.
So everything says that the datarow is for a new row as I have noticed.
Thanks
Sunil
The reason why I am saying that the datarow corresponds to new row being input is because when I step through the code, I find the values that I just input in new row to be exactly the values I find in the datarow at the mentioned index, and also the dataRowView.IsNew property is always true for the mentioned index.
So everything says that the datarow is for a new row as I have noticed.
Thanks
Sunil
0
SUNIL
Top achievements
Rank 2
Iron
answered on 16 Oct 2010, 08:53 PM
Hi Richard,
I have a video for the cases I have mentioned but it seems I cannot attach a video in forums. So I have attached a couple of images to show what I am observing.
You can see in the attached images that the new row has an index of maxIndex, as I step through the code when trying to input a new row.
I also have another scenario, but I haven't attached the gif for this, where the newStartingIndex in Add case in RowChangingEvent is 0 and not maxIndex.
Thanks
Sunil
I have a video for the cases I have mentioned but it seems I cannot attach a video in forums. So I have attached a couple of images to show what I am observing.
You can see in the attached images that the new row has an index of maxIndex, as I step through the code when trying to input a new row.
I also have another scenario, but I haven't attached the gif for this, where the newStartingIndex in Add case in RowChangingEvent is 0 and not maxIndex.
Thanks
Sunil
0
SUNIL
Top achievements
Rank 2
Iron
answered on 16 Oct 2010, 08:58 PM
Also, I have attached an image showing the new row index when in RowChangedEvent. It is the maxIndex as you can see from the watch window at bottom of attached image.
Thanks
Sunil
Thanks
Sunil
0
Emanuel Varga
Top achievements
Rank 1
answered on 16 Oct 2010, 10:05 PM
Hello guys,
Sunil, from what I've understood from reading the previous posts is that your problem is just the fact that in one grid, new rows are being added at position 0 and in another at the end, is this right?
If yes, are you sure you are not overriding somewhere the default behavior of the grid?
Best Regards,
Emanuel Varga
Sunil, from what I've understood from reading the previous posts is that your problem is just the fact that in one grid, new rows are being added at position 0 and in another at the end, is this right?
If yes, are you sure you are not overriding somewhere the default behavior of the grid?
Best Regards,
Emanuel Varga
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 12:13 AM
Emanuel,
Yes, even though the index for new row datarow is different in 2 different instances of grid, both grids are doing what they are supposed to. So I am not having a problem in that respect.
I am not overriding any behavior of radgridview.
I am sure about that.
But do you know what causes the startingindex to be 0 or maxIndex for a new row? When a user begins to edit a new row for the first time, then radgridview automatically adds a row to its row collection. This new row is getting committed later on by radgridview, if the validation event or value changing event is not cancelled. This is my understanding of how radgridview handles rows behind-the-scenes.
Thanks
Sunil
Yes, even though the index for new row datarow is different in 2 different instances of grid, both grids are doing what they are supposed to. So I am not having a problem in that respect.
I am not overriding any behavior of radgridview.
I am sure about that.
But do you know what causes the startingindex to be 0 or maxIndex for a new row? When a user begins to edit a new row for the first time, then radgridview automatically adds a row to its row collection. This new row is getting committed later on by radgridview, if the validation event or value changing event is not cancelled. This is my understanding of how radgridview handles rows behind-the-scenes.
Thanks
Sunil
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 12:54 AM
Hi,
This isn't so straightforward as Im using the latest version but give this a try. Just a grid on a form.
Sorry it's in VB
You should get a messagebox with "Name1" which is the currently selected row, not the new row.
Richard
This isn't so straightforward as Im using the latest version but give this a try. Just a grid on a form.
Sorry it's in VB
Imports
Telerik.WinControls
Imports
Telerik.WinControls.UI
Imports
System.Collections.ObjectModel
Public
Class
Form1
Private
Sub
Form1_Load(
ByVal
sender
As
System.
Object
,
ByVal
e
As
System.EventArgs)
Handles
MyBase
.Load
Dim
somethings
As
New
Somethings()
Me
.RadGridView1.DataSource = somethings.GetSomethings()
End
Sub
Private
Sub
RadGridView1_CurrentRowChanging(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.CurrentRowChangingEventArgs)
Handles
RadGridView1.CurrentRowChanging
If
TypeOf
e.CurrentRow
Is
GridViewNewRowInfo
Then
Dim
something
As
Something
something =
CType
(
Me
.RadGridView1.Rows(0).DataBoundItem, Something)
MessageBox.Show(something.Name)
End
If
End
Sub
End
Class
Public
Class
Somethings
Public
Sub
New
()
End
Sub
Public
Function
GetSomethings()
As
System.Collections.Generic.List(Of Something)
Dim
somethingList
As
New
System.Collections.Generic.List(Of Something)
somethingList.Add(
New
Something(
"Name1"
,
"Description1"
))
somethingList.Add(
New
Something(
"Name2"
,
"Description2"
))
somethingList.Add(
New
Something(
"Name3"
,
"Description3"
))
somethingList.Add(
New
Something(
"Name4"
,
"Description4"
))
Return
somethingList
End
Function
End
Class
Public
Class
Something
Private
m_Name
As
String
Private
m_Description
As
String
Public
Sub
New
()
End
Sub
Public
Sub
New
(
ByVal
name
As
String
,
ByVal
description
As
String
)
m_Name = name
m_Description = description
End
Sub
Public
Property
Name()
As
String
Get
Return
m_Name
End
Get
Set
(
ByVal
value
As
String
)
m_Name = value
End
Set
End
Property
Public
Property
Description()
As
String
Get
Return
m_Description
End
Get
Set
(
ByVal
value
As
String
)
m_Description = value
End
Set
End
Property
End
Class
You should get a messagebox with "Name1" which is the currently selected row, not the new row.
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 12:56 AM
Hi Richard,
I am using an older version, but you only tried 0 as index. Try maxIndex also in CurrentRowChanging event.
I am using a datatable as a datasource, and I don't know if that makes a difference in this situation.
Thanks
Sunil
I am using an older version, but you only tried 0 as index. Try maxIndex also in CurrentRowChanging event.
I am using a datatable as a datasource, and I don't know if that makes a difference in this situation.
Thanks
Sunil
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 01:16 AM
Hi,
If you change the index then you get back the row at that index. Just tried it. this is still what I would expect as I am referencing a specific row index.
In your case, you are saying that no matter what index you specify you are getting back the new row data. Is that right?
regards,
Richard
If you change the index then you get back the row at that index. Just tried it. this is still what I would expect as I am referencing a specific row index.
In your case, you are saying that no matter what index you specify you are getting back the new row data. Is that right?
regards,
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 01:25 AM
By the way, referencing the maxindex of the rows at that point will get the newly inserted row because the newly inserted row is at the bottom of the grid.
Richard
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 01:30 AM
Hi Richard,
I tried your code with one change- used a BindList instead of List, since List did not allow additions.
I noticed that index 0 is not new row but maxIndex is actually the new row databound item as you can see from attached image. Look at the watch window at bottom in image attached. All column values are null in watch window, and so it is not the last data row that user sees, but the new data item that is added by radgridview as soon as a user enters the new row for the first time.
Thanks
Sunil
I tried your code with one change- used a BindList instead of List, since List did not allow additions.
I noticed that index 0 is not new row but maxIndex is actually the new row databound item as you can see from attached image. Look at the watch window at bottom in image attached. All column values are null in watch window, and so it is not the last data row that user sees, but the new data item that is added by radgridview as soon as a user enters the new row for the first time.
Thanks
Sunil
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 01:32 AM
That is what I expected i.e. maxIndex is for new data row, but in another scenario, it was the 0 index that was giving the data row for new row. So I was kind of surprised.
Thanks
Sunil
Thanks
Sunil
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 01:39 AM
I think I found the reason why radgridview sometimes adds the new row datarow at 0 index and sometimes at maxIndex.
If you have defined no SORTORDER for any of the columns, then you will always get the new row inserted at maxIndex position.
But if you have defined the SORTORDER on a column, then the new row data row will be at 0 or maxIndex depending on how the null value sorts according to the SORTORDER.
Try this with your sample, or use the code below. I am defining a SORTORDER of column with index 0 as Descending and Ascending, and you will see a null value show in message box at appropriate index.
If you have defined no SORTORDER for any of the columns, then you will always get the new row inserted at maxIndex position.
But if you have defined the SORTORDER on a column, then the new row data row will be at 0 or maxIndex depending on how the null value sorts according to the SORTORDER.
Try this with your sample, or use the code below. I am defining a SORTORDER of column with index 0 as Descending and Ascending, and you will see a null value show in message box at appropriate index.
Imports
Telerik.WinControls
Imports
Telerik.WinControls.UI
Imports
System.Collections.ObjectModel
Imports
System.Collections.Generic
Imports
System.Collections
Imports
System.ComponentModel
Public
Class
Form1
Private
Sub
Form1_Load(
ByVal
sender
As
System.
Object
,
ByVal
e
As
System.EventArgs)
Handles
MyBase
.Load
Dim
somethings
As
New
Somethings()
Me
.RadGridView1.DataSource =
New
BindingList(Of Something)(somethings.GetSomethings())
CType
(
Me
.RadGridView1.Columns(0), GridViewDataColumn).SortOrder = RadSortOrder.Descending
End
Sub
Private
Sub
RadGridView1_CurrentRowChanging(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.CurrentRowChangingEventArgs)
Handles
RadGridView1.CurrentRowChanging
If
TypeOf
e.CurrentRow
Is
GridViewNewRowInfo
Then
Dim
something
As
Something
something =
CType
(
Me
.RadGridView1.Rows(0).DataBoundItem, Something)
MessageBox.Show(something.Name)
something =
CType
(
Me
.RadGridView1.Rows(
Me
.RadGridView1.Rows.Count - 1).DataBoundItem, Something)
MessageBox.Show(something.Name)
End
If
End
Sub
End
Class
Public
Class
Somethings
Public
Sub
New
()
End
Sub
Public
Function
GetSomethings()
As
System.Collections.Generic.List(Of Something)
Dim
somethingList
As
New
System.Collections.Generic.List(Of Something)
somethingList.Add(
New
Something(
"Name1"
,
"Description1"
))
somethingList.Add(
New
Something(
"Name2"
,
"Description2"
))
somethingList.Add(
New
Something(
"Name3"
,
"Description3"
))
somethingList.Add(
New
Something(
"Name4"
,
"Description4"
))
Return
somethingList
End
Function
End
Class
Public
Class
Something
Private
m_Name
As
String
Private
m_Description
As
String
Public
Sub
New
()
End
Sub
Public
Sub
New
(
ByVal
name
As
String
,
ByVal
description
As
String
)
m_Name = name
m_Description = description
End
Sub
Public
Property
Name()
As
String
Get
Return
m_Name
End
Get
Set
(
ByVal
value
As
String
)
m_Name = value
End
Set
End
Property
Public
Property
Description()
As
String
Get
Return
m_Description
End
Get
Set
(
ByVal
value
As
String
)
m_Description = value
End
Set
End
Property
End
Class
0
Emanuel Varga
Top achievements
Rank 1
answered on 17 Oct 2010, 08:19 AM
Hello again,
Sorry for getting back so late, because it seems you already have your answer.
In my point of view, it is logical for the grid to have different behaviors for sorting, filtering and other things, think of things this way, what if you were filtering on something and the newly adder row did not match the filter condition?
In order to get the newIndex of the row being added, to register to the RowsChanging event and do something like this:
And at least this way you will always now the index of the new row.
Please let me know if this helped, but again i have to warn you, because of virtualization(at least in the latest version, when you filter on a value that the new rows does not match, the index will be 0, and the row count in RadGridView1.Rows will be 0, because it is just showing the matching rows, but in the latest version there are some other events that let you handle these cases, UserAddingRow, and UserAddedRow just as a future note, if you decide to update later)
Best Regards,
Emanuel Varga
Sorry for getting back so late, because it seems you already have your answer.
In my point of view, it is logical for the grid to have different behaviors for sorting, filtering and other things, think of things this way, what if you were filtering on something and the newly adder row did not match the filter condition?
In order to get the newIndex of the row being added, to register to the RowsChanging event and do something like this:
Private
Sub
RadGridView1_RowsChanging(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.GridViewCollectionChangingEventArgs)
Handles
RadGridView1.RowsChanging
If
(e.Action = Telerik.WinControls.Data.NotifyCollectionChangedAction.Add)
Then
' you filter on something that does not match the row being added the rowindex will be 0
MessageBox.Show(
"RowIndex is "
+ e.NewStartingIndex.ToString())
End
If
End
Sub
And at least this way you will always now the index of the new row.
Please let me know if this helped, but again i have to warn you, because of virtualization(at least in the latest version, when you filter on a value that the new rows does not match, the index will be 0, and the row count in RadGridView1.Rows will be 0, because it is just showing the matching rows, but in the latest version there are some other events that let you handle these cases, UserAddingRow, and UserAddedRow just as a future note, if you decide to update later)
Best Regards,
Emanuel Varga
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 11:58 AM
Hi,
Yes, I tried that and it had the affect that you said. Really to be getting though the new row details you should be using RowsChanged not the CurrentRowChanged event.
This will get the newly inserted row
This KB Article may also be useful
Regards,
Richard
Yes, I tried that and it had the affect that you said. Really to be getting though the new row details you should be using RowsChanged not the CurrentRowChanged event.
This will get the newly inserted row
Private
Sub
RadGridView1_RowsChanged(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.GridViewCollectionChangedEventArgs)
Handles
RadGridView1.RowsChanged
If
e.Action = Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
Then
Dim
something
As
Something
Dim
newRow
As
GridViewDataRowInfo =
CType
(e.NewItems(0), GridViewDataRowInfo)
something =
CType
(newRow.DataBoundItem, Something)
MessageBox.Show(something.Name)
End
If
End
Sub
This KB Article may also be useful
Regards,
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 17 Oct 2010, 12:43 PM
Hello again,
If you just want to retrieve the actual RowIndex of the newly added row, my previous suggestion with RowsChangind and Richard's suggestion with RowsChanged will give you the actual RowIndex ONLY if you don't have a filter condition which the newly added row does not match.
If this were to happen, the new row added will have a row index of 0 and it will not be available in the Rows collection.
I cannot tell you this for a fact in the old version, but in the new version this is the expected behavior, and like i said before, this happens because of virtualization.
But like Richard pointed out, you can get the DataBoundItem in the RowsChanged event.
Best Regards,
Emanuel Varga
If you just want to retrieve the actual RowIndex of the newly added row, my previous suggestion with RowsChangind and Richard's suggestion with RowsChanged will give you the actual RowIndex ONLY if you don't have a filter condition which the newly added row does not match.
If this were to happen, the new row added will have a row index of 0 and it will not be available in the Rows collection.
I cannot tell you this for a fact in the old version, but in the new version this is the expected behavior, and like i said before, this happens because of virtualization.
But like Richard pointed out, you can get the DataBoundItem in the RowsChanged event.
Best Regards,
Emanuel Varga
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 01:15 PM
Hi Emanuel,
I nearly agree. Try this...
The RowIndex (newRow.Index) will have a value of -1 if you add a filter that does not match the current row. I'd expect it to be that and not 0.
Regards,
Richard
I nearly agree. Try this...
Private
Sub
RadGridView1_RowsChanged(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.GridViewCollectionChangedEventArgs)
Handles
RadGridView1.RowsChanged
If
e.Action = Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
Then
Dim
something
As
Something
Dim
newRow
As
GridViewDataRowInfo =
CType
(e.NewItems(0), GridViewDataRowInfo)
something =
CType
(newRow.DataBoundItem, Something)
MessageBox.Show(something.Name &
" "
& newRow.Index.ToString())
End
If
End
Sub
The RowIndex (newRow.Index) will have a value of -1 if you add a filter that does not match the current row. I'd expect it to be that and not 0.
Regards,
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 17 Oct 2010, 01:19 PM
Hello Richard,
This is even stranger, if you add also the RowsChanging event, there it will have a RowIndex of 0, and in RowsChanged it has an index of -1?
In my point of view, it should at least be consistent, either -1 in both events or 0 in both.
Best Regards,
Emanuel Varga
This is even stranger, if you add also the RowsChanging event, there it will have a RowIndex of 0, and in RowsChanged it has an index of -1?
In my point of view, it should at least be consistent, either -1 in both events or 0 in both.
Best Regards,
Emanuel Varga
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 01:28 PM
Hi again Emanuel,
Can you show me what you mean?
If you try this..
then the e.NewItems count is 1 but the e.NewItems(0) object is Nothing (so of course the code above throws a null reference exception)
meaning that the the only time to get the row index of the newly added row is in the RowsChanged event, and not RowsChanging.
Regards,
Richard
Can you show me what you mean?
If you try this..
Private
Sub
RadGridView1_RowsChanging(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.GridViewCollectionChangingEventArgs)
Handles
RadGridView1.RowsChanging
If
e.Action = Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
Then
Dim
newRow
As
GridViewDataRowInfo =
CType
(e.NewItems(0), GridViewDataRowInfo)
MessageBox.Show(newRow.Index.ToString())
End
If
End
Sub
meaning that the the only time to get the row index of the newly added row is in the RowsChanged event, and not RowsChanging.
Regards,
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 17 Oct 2010, 01:37 PM
Hello Richard,
So, the whole point of the RowsChanging event is to do 2 things:
1. To cancel the operation
2. Provide you with the old Index of the row if any and the new index of the row, right? Please check my previous example with the RowsChanging and you will see what i mean, i wasn't talking about the RowInfo of the new row, because the RowInfo for the row is created just in the RowsChanged event, because of the reason 1 (being able to cancel it and then it would just be a waste of memory)
But if you put the code in my example in the RowsChanging it will give an index of 0 and after that it will be followed by the RowsChanged event when the row has an index of -1, which in a way is logical if filter is being applied between these two events but it might cause some misunderstandings.
@Sunil, hope you found your answer, in one / some of these posts
Best Regards,
Emanuel Varga
So, the whole point of the RowsChanging event is to do 2 things:
1. To cancel the operation
2. Provide you with the old Index of the row if any and the new index of the row, right? Please check my previous example with the RowsChanging and you will see what i mean, i wasn't talking about the RowInfo of the new row, because the RowInfo for the row is created just in the RowsChanged event, because of the reason 1 (being able to cancel it and then it would just be a waste of memory)
But if you put the code in my example in the RowsChanging it will give an index of 0 and after that it will be followed by the RowsChanged event when the row has an index of -1, which in a way is logical if filter is being applied between these two events but it might cause some misunderstandings.
@Sunil, hope you found your answer, in one / some of these posts
Best Regards,
Emanuel Varga
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 01:42 PM
Hi,
"But if you put the code in my example in the RowsChanging it will give an index of 0 and after that it will be followed by the RowsChanged event when the row has an index of -1, which in a way is logical if filter is being applied between these two events but it might cause some misunderstandings."
Yep, I realised what you meant after I posted and went downstairs. :o)
Best wishes
Richard
"But if you put the code in my example in the RowsChanging it will give an index of 0 and after that it will be followed by the RowsChanged event when the row has an index of -1, which in a way is logical if filter is being applied between these two events but it might cause some misunderstandings."
Yep, I realised what you meant after I posted and went downstairs. :o)
Best wishes
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 04:48 PM
Emanuel and Richard,
I appreciate all your help and feedback.
The story is slightly different. Please read below. I am clearing all filters as soon as user goes to a new row cell and starts editing it. So filters is not a problem, but the sort order sure makes things complex.
I appreciate all your help and feedback.
The story is slightly different. Please read below. I am clearing all filters as soon as user goes to a new row cell and starts editing it. So filters is not a problem, but the sort order sure makes things complex.
- I have a new row at top.
- My grid is sorted in descending order of 'attributename' column.
- I click on first column in new row so my cursor gets placed in a new row cell. As soon as this happens, RowsChanging and RowsChanged events fire in which e.Action == NotifyCollectionChangedAction.Add is true and e.NewStartingIndex = maxIndex. This means a new EMPTY datarow has already been placed by the radgridview engine, but at a position that satisfies the sort order of the grid.
- So far the story is going as expected. But things are going to change soon.
- I input a value in each cell of new row, and then press ENTER. The RowsChanging and RowsChanged event are not fired now. Surprised? We have the 'CurrentRowChanging' and 'CurrentRowChanged' events fire now. In 'CurrentRowChanging', the current row is new row just input and its index in datarows is the e.NewStartingIndex we saw in RowsChanged event. This means the new datarow has not been placed in the rows collection according to existing sort order i.e. the datarows collection have not been sorted even though the empty datarow has been put into the rows collection.
- Now comes the shock. So be prepared !!!! In 'CurrentrowChanged' event that fires just after 'CurrentRowChanging' event, e.OldRow is GridViewNewRowInfo, and if you try to use e.NewStartingIndex that you obtained as the index of new row's datarow in RowsChanged event, then you are in for a BIG SHOCK because the index of new data row has changed now, since the new datarows collection got its sorting refreshed sometimes after the 'CurrentRowChanging' event but before the 'CurrentRowChanged' event. As an example, if you input a value of 'Sunil' for attributename, then the new datarow has been placed at the sort order position so that descending sort order of attributename is satisfied. Probably somewhere in the middle, so that its index is neither 0 nor maxIndex.
- So to get the real index of new datarow in 'CurrentRowChanged' event, I used some custom code like below. In my grid, the invisible column of 'AttributeId' is still DBNull.Value since it is the integer primary key from database, and the new datarow has still not been written to database, and hence it is the only way to get the index of new datarow in this event. But this is a very customized way of getting the correct index of new datarow. Also, I don't know if the FirstORDefault find method is going to take a lot of time if there 5,000 rows or so. Is there a generic way I can use here, that helps to cut down the times for finding the new datarow and can be used in all situations?
if
(e.OldRow
is
GridViewNewRowInfo && attributesRadGridView.Rows.Count > 0 )
{
DataRowView dataRowView =
null
;
//line below gives the just added row
GridViewDataRowInfo justAddedRow = attributesRadGridView.Rows.FirstOrDefault(row => row.Cells[
"attributeId"
].Value == DBNull.Value);
if
(justAddedRow ==
null
|| justAddedRow.DataBoundItem ==
null
)
{
return
;
}
dataRowView = justAddedRow.DataBoundItem
as
DataRowView;
// attributesRadGridView.Rows[_newRowIndexInDataRows].DataBoundItem as DataRowView;
if
(dataRowView !=
null
&& dataRowView.Row.RowState == DataRowState.Added)
{
errorRadLabel.Text =
string
.Empty;
CreateAttribute(dataRowView.Row);
//creates the new row in database
}
}
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 05:13 PM
Hi again,
Did you have a look at the KB Article?
This shows that
so I'm not so shocked by that part, though I'd agree it looks a little odd.
I have to say again that I think the only way to get the row index when no filters are on (which you said isn't a problem) is to use the RowsChanged event. However, you said that it isn't firing. Is there anything that could have unregistered your event handler for this event?
Also, I'd like to re-confirm your objective. Is it that you are simply trying to track the newly inserted row? If so, then the KB Article above should be able to help you with that.
All the best
Richard
Did you have a look at the KB Article?
This shows that
if
(e.OldRow
is
GridViewNewRowInfo)
I have to say again that I think the only way to get the row index when no filters are on (which you said isn't a problem) is to use the RowsChanged event. However, you said that it isn't firing. Is there anything that could have unregistered your event handler for this event?
Also, I'd like to re-confirm your objective. Is it that you are simply trying to track the newly inserted row? If so, then the KB Article above should be able to help you with that.
All the best
Richard
0
Emanuel Varga
Top achievements
Rank 1
answered on 17 Oct 2010, 05:14 PM
Hello again Sunil,
In my point of view, the most simplest and straight forward way of handling new data is to cancel the internal data creation of the grid, and just take the values from the cells and create your own row, or business object or whatever you want, and after that add it to your collection, this way you know what the position is, and everything.
This is pretty straightforward to do in the newer versions with the UserAddingRow and UserAddedRow, but for the older versions, i don't even know where to start.
In my point of view this is the biggest problems when using custom controls and not having the latest versions, because of the fact that the controls grow, fill in some missing logic, change the way things are done, it's pretty hard to guess how things were done in the 2008 version.
For example, with the new version, when you fill all the data in the new row and press enter (confirm) that's when the RowsChanging / RowsChanged event fires not when you click on the new row and start entering data. The second thing, in the new grid, if you enter some data in the new row field, and press enter, the first time the CurrentRowChanging fires is to move the cursor to the first row of the grid, and then it fires again to reflect the newly added row.
Honestly i don't know how i can help you more, the behavior of today and the behavior from then is totally different (let's not even mention that the behavior the grid had in 2010 Q1 is totally different than the one it has now) in a lot of essential ways.
But, If you want my opinion, you have 2 options:
- 1 (simpler one), store the sort descriptors in a variable, clear sorting, and after the CurrentRowChanged (if this is the event you are using) put back the sort descriptors on the grid. (you may want to suspend the layout of the grid while you are doing all of this), but it should work.
- 2 (a more complex option, but in my point of view a better one in time if you plan to extend it (but i have to note here that you will be trying to mimic what telerik has already done during the years)) is to create a custom grid, create some events, like the ones that are available now in the grid, UserAddingRow and UserAddedRow, handle the CellBeginEdit and CellEndEdit events and if the current row is the grid new row and Enter was pressed fire the UserAddingRowEvent with the newRowElement in order to be able to cancel the event but also take the values from the cells and create a new object that can be added to your collection at what index you desire. This is just a basic suggestion, it will be more complicated than just this, but at least you will be able to do what you require.
Hope that at least some of my suggestions helped, if you have any other questions or comments, please let me know, i will do my best to answer them
Best Regards,
Emanuel Varga
In my point of view, the most simplest and straight forward way of handling new data is to cancel the internal data creation of the grid, and just take the values from the cells and create your own row, or business object or whatever you want, and after that add it to your collection, this way you know what the position is, and everything.
This is pretty straightforward to do in the newer versions with the UserAddingRow and UserAddedRow, but for the older versions, i don't even know where to start.
In my point of view this is the biggest problems when using custom controls and not having the latest versions, because of the fact that the controls grow, fill in some missing logic, change the way things are done, it's pretty hard to guess how things were done in the 2008 version.
For example, with the new version, when you fill all the data in the new row and press enter (confirm) that's when the RowsChanging / RowsChanged event fires not when you click on the new row and start entering data. The second thing, in the new grid, if you enter some data in the new row field, and press enter, the first time the CurrentRowChanging fires is to move the cursor to the first row of the grid, and then it fires again to reflect the newly added row.
Honestly i don't know how i can help you more, the behavior of today and the behavior from then is totally different (let's not even mention that the behavior the grid had in 2010 Q1 is totally different than the one it has now) in a lot of essential ways.
But, If you want my opinion, you have 2 options:
- 1 (simpler one), store the sort descriptors in a variable, clear sorting, and after the CurrentRowChanged (if this is the event you are using) put back the sort descriptors on the grid. (you may want to suspend the layout of the grid while you are doing all of this), but it should work.
- 2 (a more complex option, but in my point of view a better one in time if you plan to extend it (but i have to note here that you will be trying to mimic what telerik has already done during the years)) is to create a custom grid, create some events, like the ones that are available now in the grid, UserAddingRow and UserAddedRow, handle the CellBeginEdit and CellEndEdit events and if the current row is the grid new row and Enter was pressed fire the UserAddingRowEvent with the newRowElement in order to be able to cancel the event but also take the values from the cells and create a new object that can be added to your collection at what index you desire. This is just a basic suggestion, it will be more complicated than just this, but at least you will be able to do what you require.
Hope that at least some of my suggestions helped, if you have any other questions or comments, please let me know, i will do my best to answer them
Best Regards,
Emanuel Varga
0
Accepted
SUNIL
Top achievements
Rank 2
Iron
answered on 17 Oct 2010, 05:54 PM
Hi Richard,
I appreciate all the help from you and Emanuel. My problem seems to be solved. Please read below for the solution.
I am not unregistering any events, but that's the sequence of events in default radgridview.
What you suggested for tracking new row worked. I can use your suggestion to get the index of new row in 'CurrentRowChanged' event , even though the index of new datarow may have changed due to an existing sort order. This also provides a generic way of getting new data row index in 'CurrentRowChanged' event that can be used in all situations, without incurring any extra processing time in finding the index. In my custom code I was searching the rows collection to find the index of new data row, that will always add to processing time, and also I would need to come up with different code for every situation.
In code block below, the values of i and j are always equal, which means I can get rid of logic related to justAddedRow, and simply use _newRow.
Thanks
Sunil
if
(e.OldRow
is
GridViewNewRowInfo && attributesRadGridView.Rows.Count > 0 )
{
DataRowView dataRowView =
null
;
//line below gives the just added row
GridViewDataRowInfo justAddedRow = attributesRadGridView.Rows.FirstOrDefault(row => row.Cells[
"attributeId"
].Value == DBNull.Value);
if
(justAddedRow ==
null
|| justAddedRow.DataBoundItem ==
null
)
{
return
;
}
int
i = attributesRadGridView.Rows.IndexOf(justAddedRow);
int
j = attributesRadGridView.Rows.IndexOf(_newRow);
dataRowView = justAddedRow.DataBoundItem
as
DataRowView;
// attributesRadGridView.Rows[_newRowIndexInDataRows].DataBoundItem as DataRowView;
if
(dataRowView !=
null
&& dataRowView.Row.RowState == DataRowState.Added)
{
errorRadLabel.Text =
string
.Empty;
CreateAttribute(dataRowView.Row);
//creates the new row in database
}
}
0
Richard Slade
Top achievements
Rank 2
answered on 17 Oct 2010, 06:01 PM
So glad you managed to get it sorted.
Please remember to mark as answer so others can quickly find the answer.
All the best
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 18 Oct 2010, 03:50 PM
There is one scenario, where the new data row tracking using the approach in suggested answer, will fail.
That case is when:
For this exceptional case, the approach that works is the one that uses 'justAddedRow' in suggested answer, where you need to check if an invisible column like 'AttributeId' has a value of DBNull.Value. For a new row, this column is never populated, since its a primary key from database.
Thanks
Sunil
That case is when:
- user inputs a filter like 'sdsd' in a filter cell
- and then clicks on the new row
For this exceptional case, the approach that works is the one that uses 'justAddedRow' in suggested answer, where you need to check if an invisible column like 'AttributeId' has a value of DBNull.Value. For a new row, this column is never populated, since its a primary key from database.
Thanks
Sunil
0
Richard Slade
Top achievements
Rank 2
answered on 18 Oct 2010, 03:55 PM
Hi,
I think I know what you mean. If you apply a filter and still do this...
then you have access to the new row data, but the index is at -1 9as it is currently hidden)
Richard
I think I know what you mean. If you apply a filter and still do this...
Private
Sub
RadGridView1_RowsChanged(
ByVal
sender
As
System.
Object
,
ByVal
e
As
Telerik.WinControls.UI.GridViewCollectionChangedEventArgs)
Handles
RadGridView1.RowsChanged
If
e.Action = Telerik.WinControls.Data.NotifyCollectionChangedAction.Add
Then
Dim
something
As
Something
Dim
newRow
As
GridViewDataRowInfo =
CType
(e.NewItems(0), GridViewDataRowInfo)
something =
CType
(newRow.DataBoundItem, Something)
MessageBox.Show(something.Name &
" "
& newRow.Index.ToString())
End
If
End
Sub
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 18 Oct 2010, 04:44 PM
Hi Richard,
Since newRow is null and also newIndex == -1, so casting newRow.DataBoundItem to Something will also fail and throw a NullReference exception.
Thanks
Sunil
Since newRow is null and also newIndex == -1, so casting newRow.DataBoundItem to Something will also fail and throw a NullReference exception.
Thanks
Sunil
0
Richard Slade
Top achievements
Rank 2
answered on 18 Oct 2010, 04:49 PM
Hi,
I don't believe that's the case. You do have access to the NewRow object, it's just that it's index is -1.
Richard
I don't believe that's the case. You do have access to the NewRow object, it's just that it's index is -1.
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 18 Oct 2010, 05:03 PM
Hi Richard,
I tried and it is happening. It actually throws an error as soon as you move from a filter textbox with 'sdsd' to a cell in new row.
The fact is when newIndex == -1, then newItems[0] seems to be null.
Thanks
Sunil
I tried and it is happening. It actually throws an error as soon as you move from a filter textbox with 'sdsd' to a cell in new row.
The fact is when newIndex == -1, then newItems[0] seems to be null.
Thanks
Sunil
0
Richard Slade
Top achievements
Rank 2
answered on 18 Oct 2010, 05:06 PM
ok - This doesn't happen in the later version. I can enter a filter value, then enter data for the new row, and I can get a messagebox with -1 for the index and the newdata object.
As a workaround, you could clear the filters when trying to get the new row perhaps?
Richard
As a workaround, you could clear the filters when trying to get the new row perhaps?
Richard
0
SUNIL
Top achievements
Rank 2
Iron
answered on 18 Oct 2010, 05:11 PM
That may be true, since I am using Q1 2008 SP1, and this issue may have been removed in the version you are using.
Even after clearing filters, the newIndex == -1 and newRow == null, in my version. So it may be an issue with my version.
Even after clearing filters, the newIndex == -1 and newRow == null, in my version. So it may be an issue with my version.