Search code examples
wpfdatagridwpfdatagrid

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?


Solution

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