How to Keep New at Top of DataGrid

RogerSchlueter-7899 1,426 Reputation points
2025-04-06T01:20:04.2266667+00:00

Consider the following code which sets up a DataGrid:

ocExpenses.OrderByDescending(Function(ve) ve.ChargeDate)
dgExpenses.ItemsSource = ocExpenses
Dim ecv As IEditableCollectionView = dgExpenses.Items
ecv.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning


where:

ocExpenses is an ObservableCollection(OF Expense) and dgExpenses is a DataGrid. The first line sorts the expenses by descending ChargeDate and the second line populates the DataGrid. The last two lines put the new expense row at the top. The result a grid with the new row at the top followed by the latest expense just below that. All that is working.

But when I enter data for a new expense and press Enter, the new row jumps to the bottom of the DataGrid which means it is not visible and the DataGrid is no longer in sort order.

Is there a way to prevent the "jump"?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,853 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Hongrui Yu-MSFT 5,255 Reputation points Microsoft External Staff
    2025-04-08T03:50:38.26+00:00

    Hi, @RogerSchlueter-7899. Welcome to Microsoft Q&A. 

    ocExpenses.OrderByDescending(Function(ve) ve.ChargeDate) will return the sorted result and will not sort the source data.

    The initial sorting could be done as follows:

            ocExpenses = New ObservableCollection(Of Expenses)(ocExpenses.OrderByDescending(Function(ve) ve.ChargeDate))
            dgExpenses.ItemsSource = ocExpenses
            Dim ecv As IEditableCollectionView = dgExpenses.Items
            ecv.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning
    

    New data needs to be inserted at the top. You could refer to the following method to adjust the insertion position in the RowEditEnding event.

    <DataGrid Name="dgExpenses" AutoGenerateColumns="True"  CanUserAddRows="True"  RowEditEnding="dgExpenses_RowEditEnding" />
    
    	'Avoid infinite recursive calls To dgExpenses.CommitEdit(DataGridEditingUnit.Row, True) In dgExpenses_RowEditEnding
        Public isEdit As Boolean = True
    
        Private Sub dgExpenses_RowEditEnding(sender As Object, e As DataGridRowEditEndingEventArgs)
            If isEdit Then
                isEdit = False
                '
                dgExpenses.CommitEdit(DataGridEditingUnit.Row, True)
    
                Dim newItem = ocExpenses.LastOrDefault()
                If newItem IsNot Nothing Then
                    ocExpenses.Remove(newItem)
                    ocExpenses.Insert(0, newItem)
                End If
    
                isEdit = True
            End If
        End Sub
    

    If you want to keep the order after insertion, you could compare the elements of ocExpenses in dgExpenses_RowEditEnding to find the position to be inserted and insert it.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.