单元格上的 WPF DataGrid 源更新已更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5028556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:35:25  来源:igfitidea点击:

WPF DataGrid source updating on cell changed

wpfdatagridwpfdatagrid

提问by Khaled

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

我是 WPF 的新手,我用它来构建销售点系统。

I have a DataGridcontrol in the main window bound to an ObservableCollectionof 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.

DataGrid在主窗口中有一个绑定到ObservableCollectionof的控件Item,收银员将输入/扫描要出售的商品,每个商品的默认数量为 1,但收银员可以手动更改数量。

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 DataGridto update the source when the cell is changed rather than the row?

无论如何,DataGrid当单元格而不是行被更改时,是否强制更新源?

采纳答案by grantnz

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

是的,这是可能的。您的问题与DataGrid基本相同- 更改编辑行为

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

下面的代码主要来自 Quartermeister 的回答,但我添加了一个DependencyPropertyBoundCellLevel,当您需要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;
        }
    }
}

回答by Almund

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

将 应用于UpdateSourceTrigger=LostFocus每个绑定。它对我来说就像一种魅力。

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

回答by mattanja

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.

接受的答案中的代码对我不起作用,因为从ItemContainerGenerator.ContainerFromItem(item)结果中提取的行为null 并且循环非常慢。

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

该问题的一个更简单的解决方案是此处提供的代码: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;
 }
}

回答by Mitesh

Almund is right. UpdateSourceTrigger=LostFocuswill 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.

阿尔蒙德是对的。UpdateSourceTrigger=LostFocus在你的情况下效果最好。正如您所提到的,当您移动到下一行时,您的源正在更新,这意味着我猜,您正在使用ObservableCollection<T>绑定您DataGridItemSource. 因为这是你实现你想要的东西所需要的。

<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.

您需要添加"UpdateSourceTrigger=LostFocus"到每一列。