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
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;
}
}
}
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;
}
}
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.
<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.
Apply the UpdateSourceTrigger=LostFocus
to each binding. It worked like a charm for me.
<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />