WPF DataGrid source updating on cell changed

30,295

Solution 1

Yes, this is possible. Your question is basically the same as DataGrid - change edit behaviour

The code below is mostly from Quartermeister's answer but I added a DependencyProperty BoundCellLevel that you can set when you need a DataGrid binding to be updated when the current cell changes.

public class DataGridEx : DataGrid
{
    public DataGridEx()
    {

    }

    public bool BoundCellLevel
    {
        get { return (bool)GetValue(BoundCellLevelProperty); }
        set { SetValue(BoundCellLevelProperty, value); }
    }

    public static readonly DependencyProperty BoundCellLevelProperty =
        DependencyProperty.Register("BoundCellLevel", typeof(bool), typeof(DataGridEx), new UIPropertyMetadata(false));

    protected override Size MeasureOverride(Size availableSize)
    {
        var desiredSize = base.MeasureOverride(availableSize);
        if ( BoundCellLevel )
            ClearBindingGroup();
        return desiredSize;
    }

    private void ClearBindingGroup()
    {
        // Clear ItemBindingGroup so it isn't applied to new rows
        ItemBindingGroup = null;
        // Clear BindingGroup on already created rows
        foreach (var item in Items)
        {
            var row = ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
            row.BindingGroup = null;
        }
    }
}

Solution 2

Apply the UpdateSourceTrigger=LostFocus to each binding. It worked like a charm for me.

<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />

Solution 3

The code in the accepted answer didn't work for me since the row fetched from ItemContainerGenerator.ContainerFromItem(item) results in null and the loop be quite slow.

A more simple solution to the question is the code provided here: http://codefluff.blogspot.de/2010/05/commiting-bound-cell-changes.html

private bool isManualEditCommit;
private void HandleMainDataGridCellEditEnding(
  object sender, DataGridCellEditEndingEventArgs e) 
{
 if (!isManualEditCommit) 
 {
  isManualEditCommit = true;
  DataGrid grid = (DataGrid)sender;
  grid.CommitEdit(DataGridEditingUnit.Row, true);
  isManualEditCommit = false;
 }
}

Solution 4

Almund is right. UpdateSourceTrigger=LostFocus will work best in you case. And as you have mentioned that your source is updating when you move to next row, that means I guess, you are using ObservableCollection<T> to bind your DataGrid's ItemSource. Because that is what which you need to achieve what you want.

<DataGridTextColumn Header="Quantity" Binding="{Binding Quantity,
                    Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
<DataGridTextColumn Header="Total Price" Binding="{Binding TotalPrice,
                    Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />

You need to add "UpdateSourceTrigger=LostFocus" to each of your columns.

Share:
30,295

Related videos on Youtube

Khaled
Author by

Khaled

Updated on July 09, 2022

Comments

  • Khaled
    Khaled almost 2 years

    I am new to the WPF ,and i use it to build a point of sale system.

    I have a DataGrid control in the main window bound to an ObservableCollection of Item, the cashier will enter/scan the items to be sold the default quantity for each item is 1 but it is available for the cashier to change the quantity manually.

    Whenever I change the quantity, it should update the total price with the sum of the items' prices when I leave the cell to another cell on the row, but it doesn't happen, the source is updated only when I go to another row not another cell in the same row.

    Is there anyway to force the DataGrid to update the source when the cell is changed rather than the row?

  • retanik
    retanik over 10 years
    +1 Better solution of problem stated. Other cell values should be updated as soon as focus is lost on the cell instead of when focus is lost on the row (default).
  • Mageician
    Mageician over 10 years
    Exactly what I needed! Thanks!
  • Jamaxack
    Jamaxack over 8 years
    Great! Also UpdateSourceTrigger=PropertyChanged works right after changing cell.
  • RackM
    RackM about 6 years
    This must be the solution
  • LuckyLuke82
    LuckyLuke82 about 3 years
    I have been struggling with this one. Should be accepted as answer.

Related