Need urgent help

34 posts, 2 answers
  1. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 15 Oct 2010 Link to this post

    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:
    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;
                       
                    }
                 }
  2. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 16 Oct 2010 Link to this post

    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;
    or
    dataRowView = attributesRadGridView.Rows[attributesRadGridView.Rows.Count - 1].DataBoundItem as DataRowView;
     is not actually the new row at all but getting the data bound item from the row at that index.

    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
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  5. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  6. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  7. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 16 Oct 2010 Link to this post

    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
  8. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  9. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 16 Oct 2010 Link to this post

    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
    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
  10. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  11. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 16 Oct 2010 Link to this post

    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
  12. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 16 Oct 2010 Link to this post

    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
  13. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  14. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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
  15. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 16 Oct 2010 Link to this post

    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.
    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
  16. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 17 Oct 2010 Link to this post

    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:
    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
  17. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    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
    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
  18. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 17 Oct 2010 Link to this post

    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

  19. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    Hi Emanuel,

    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
  20. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 17 Oct 2010 Link to this post

    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
  21. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    Hi again Emanuel,

    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
    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
  22. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 17 Oct 2010 Link to this post

    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
  23. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    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

  24. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 17 Oct 2010 Link to this post

    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 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
                      }
                  }

  25. Answer
    Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    Hi again,

    Did you have a look at the KB Article?
    This shows that
    if (e.OldRow is GridViewNewRowInfo)
    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
  26. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 17 Oct 2010 Link to this post

    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
  27. Answer
    Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 17 Oct 2010 Link to this post


    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
                    }
                }
  28. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 17 Oct 2010 Link to this post

    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
  29. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 18 Oct 2010 Link to this post

    There is one scenario, where the new data row tracking using the approach in suggested answer, will fail.
    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
  30. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 18 Oct 2010 Link to this post

    Hi,

    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
    then you have access to the new row data, but the index is at -1 9as it is currently hidden)

    Richard
  31. Sunil
    Sunil avatar
    230 posts
    Member since:
    Jan 2004

    Posted 18 Oct 2010 Link to this post

    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
Back to Top
UI for WinForms is Visual Studio 2017 Ready