Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid source updating on cell changed

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?

like image 778
Khaled Avatar asked Feb 17 '11 11:02

Khaled


3 Answers

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

<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
like image 149
Almund Avatar answered Oct 21 '22 02:10

Almund


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;
 }
}
like image 30
mattanja Avatar answered Oct 21 '22 03:10

mattanja


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;
        }
    }
}
like image 40
grantnz Avatar answered Oct 21 '22 02:10

grantnz