Обновление источника WPF DataGrid в ячейке изменено - PullRequest
20 голосов
/ 17 февраля 2011

Я новичок в WPF и использую его для построения системы торговых точек.

У меня есть элемент управления DataGrid в главном окне, привязанный к ObservableCollection из Item, кассир будет вводить / сканировать предметы, подлежащие продаже, количество по умолчанию для каждого предмета равно 1, но оно доступно для Касса для изменения количества вручную.

Всякий раз, когда я меняю количество, оно должно обновлять общую цену с суммой цен товаров, когда я покидаю ячейку в другую ячейку в строке, но этого не происходит, источник обновляется только тогда, когда я иду в другую строку, а не в другую ячейку в той же строке.

Есть ли способ заставить DataGrid обновить источник при изменении ячейки, а не строки?

Ответы [ 4 ]

58 голосов
/ 23 августа 2012

Применить UpdateSourceTrigger=LostFocus к каждому переплету. Для меня это сработало как шарм.

<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
9 голосов
/ 13 июля 2012

Код в принятом ответе не работает для меня, так как строка, извлеченная из ItemContainerGenerator.ContainerFromItem(item), приводит к нулю, и цикл будет довольно медленным.

Более простым решением вопроса является приведенный здесь код: 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;
 }
}
3 голосов
/ 22 февраля 2011

Да, это возможно.Ваш вопрос в основном такой же, как DataGrid - измените режим редактирования

Приведенный ниже код в основном из ответа Quartermeister, но я добавил DependencyProperty BoundCellLevel, который вы можете установить, когда вам нужно DataGrid привязка обновляется при изменении текущей ячейки.

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;
        }
    }
}
1 голос
/ 16 мая 2013

Альмунд прав.UpdateSourceTrigger=LostFocus будет работать лучше всего в вашем случае.И поскольку вы упомянули, что ваш источник обновляется при переходе к следующему ряду, это означает, что, я думаю, вы используете ObservableCollection<T> для привязки DataGrid ItemSource.Потому что это то, что вам нужно для достижения того, чего вы хотите.

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

Вам необходимо добавить "UpdateSourceTrigger=LostFocus" к каждому из ваших столбцов.

...