单元格上的 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
WPF DataGrid source updating on cell changed
提问by Khaled
I am new to the WPF ,and i use it to build a point of sale system.
我是 WPF 的新手,我用它来构建销售点系统。
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.
我DataGrid
在主窗口中有一个绑定到ObservableCollection
of的控件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 DataGrid
to 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 DependencyProperty
BoundCellLevel that you can set when you need a DataGrid
binding to be updated when the current cell changes.
下面的代码主要来自 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;
}
}
}
回答by Almund
Apply the UpdateSourceTrigger=LostFocus
to 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=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.
阿尔蒙德是对的。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}" />
You need to add "UpdateSourceTrigger=LostFocus"
to each of your columns.
您需要添加"UpdateSourceTrigger=LostFocus"
到每一列。