Share via

Unbound columns lost cell values on sorting in datagrid in WPF

Pratham Jain 351 Reputation points
2026-02-07T16:02:21.8666667+00:00

Hi All,

I have a WPF datagrid on the screen which has three unbound columns. These columns are calculated or updated from database based on values in other columns. The issue is that whenever user click on column header to sort the column these unbound columns lost their values and data is displayed in only bound columns. Please advise how can I recalculate these unbound columns ASAP.

Regards,

Pratham

Developer technologies | Windows Presentation Foundation
0 comments No comments
{count} votes

Answer accepted by question author
  1. Adiba Khan 2,265 Reputation points Microsoft External Staff
    2026-02-09T07:19:01.8133333+00:00

    Thank you for reaching out. In WPF DataGrid, when you sort by clicking on a column header, the control recreates the row containers based on the sorted ItemSource. If your columns are unbound, their values are not persisted, which is why they appear blank after sorting. This is expected behavior in WPF.

    Recommended Approach

    Best Practice: Convert Unbound Columns to Bound Columns

    if the values are calculated from other columns or database values, expose them as properties in your data model.

    • Add calculated properties to your ViewModel/ model class.
    • Raise INotifyPropertyChanged when dependent values change.
    • Bind the DataGrid columns directly to those properties. Example:
        public string CalculatedValue
        {
        	get => _calculatedValue;
        	set
        	{
        		_calculatedValue = value;
        		OnPropertyChanged(nameof(CalculatedValue));
        	}
        }
      

    This ensures values remain intact during sorting, filtering and virtualization

    Use IValueConverter or MultiBinding

    if column value is derived from multiple fields:

    <DataGridTextColumn Header="Total">
    	<DataGridTextColumn.Binding>
    		<MultiBinding Converter="{StaticResource TotalConverter}">
    			<Binding Path="Value1"/>
    			<Binding Path="Value2"/>
    		</MultiBinding>
    	</DataGridTextColumn.Binding>
    </DataGridTextColumn>
    

    This keeps calculations fully data-bound and sorting-safe.

    Avoid setting value in Ui events

    Do not rely on:

    • LoadingRow
    • RowLoaded
    • Code-behind cell assignment

    These will be lost whenever sorting, grouping or virtualization occurs.

    Please let us know if you require any further assistance we’re happy to help. If you found this information useful, kindly mark this as "Accept Answer".


3 additional answers

Sort by: Most helpful
  1. BillAli-2762 0 Reputation points
    2026-02-12T16:03:48.01+00:00

    DataColumn eanColumn = new DataColumn("EANCode", typeof(string));

    eanColumn.ReachOnly = true;

    eanColumn.AllowDBNull = true;

    dataTable.Columns.Add(eanColumn);

    0 comments No comments

  2. Adiba Khan 2,265 Reputation points Microsoft External Staff
    2026-02-12T11:13:31.13+00:00

    Thank you for detailed clarification. You are correct in your observation.

    This behavior is expected because once the olumn becomes part of the DataTable, it is treated as a regular data column by:

    • DataRowValidation
    • DataTable.GetErrors()
    • SqlDataAdapter.Update()

    Solution

    You need the column:

    • To exist in DataTable (to avoid losing values during sorting)
    • But Not to particiate in Validation
    • And Not to be sent to database during Update() The correct way to achieve this:

    Mark the column as readonly and Non-Updatable

    When adding your calculated column:

    DataColumn eanColumn = new DataColumn("EANCode", typeof(string));
    eanColumn.ReachOnly = true;
    eanColumn.AllowDBNull = true;
    dataTable.Columns.Add(eanColumn);
    

    This prevents user edits and validation conflicts.

    Exclude Column from SqlDataAdapter updates(very important)

    Because you are using SqlDataAdapter.Update(), you must ensure the column is NOT included in insert/Update commands.

    If you are using SqlCommandBuilder, it automatically generates commands including all columns.

    To exclude the column:

    Option A- Remove from UpdateCommand manually

    After SqlCommandBuilder builds commands:

    adapter.UpdateCommand.Parameters.Remoce(
    	adapter.UpdateCommand.Parameters["@EANCode"]);
    
    pter.InsertCommand.Parameters.Remoce(	
    	adapter.InsertCommand.Parameters["@EANCode"]);
    

    or

    Option B - Set column mapping to hidden

    before filling

    adapter.TableMappings[0].ColumnMappings.Add("EANCode", "EANCode").DataSetColumn = "EANCode";
    

    Then set:

    dataTable.Columns["EANCode"].ColumnMapping = MappingType.Hidden;
    
    

    This prevents the column from being included in generated SQL commands

    Prevent Validation on that column only

    Since you are using:

    <DataGrid.RowValidationRules>
    	<local:DataRowValidation ValidationStep="UpdateValue"/>
    
    </DataGrid.RowValidationRules>
    

    your validation rule likely checks the entire row.

    Inside your custom DataRowValidation, modify it to ignore the calculated column:

    if (row.Table.Columns.Contains("EANCode"))
    {
    	row.ClearErrors();
    }
    

    Or better validate only DB-backed Columns:

    foreach (DataColumn col in row.Table.Columns)
    {
    	if(col.ColumnMapping != MappingType.Hidden)
    	{
    			//validate only these
    	}
    }
    

    Please let us know if you require any further assistance we’re happy to help. If you found this information useful, kindly mark this as "Accept Answer".


  3. Q&A Assist
    2026-02-07T16:02:39.5066667+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    When using a WPF DataGrid with unbound columns, it's important to note that sorting by bound columns can lead to the loss of values in unbound columns. To maintain the values in your unbound columns during sorting, you need to implement virtual mode. This involves setting the VirtualMode property to true and handling the CellValueNeeded and CellValuePushed events to manage the values in the unbound columns.

    Here are the steps you can follow to recalculate and maintain the values of your unbound columns:

    1. Set VirtualMode to True: Enable virtual mode on your DataGrid.
    2. Handle CellValueNeeded Event: In this event, you can recalculate the values for your unbound columns based on the current state of the bound columns.
    3. Handle CellValuePushed Event: This event allows you to update the underlying data source when the user edits the unbound columns.

    By implementing these steps, you can ensure that the values in your unbound columns are recalculated and maintained even when the user sorts the DataGrid by bound columns.

    0 comments No comments

Your answer

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