私はWPFを初めて使用し、それを使用してPOSシステムを構築します。
メインウィンドウにDataGrid
のObservableCollection
にバインドされたItem
コントロールがあります。レジ係は、販売するアイテムを入力/スキャンします。各アイテムのデフォルトの数量は1です。ただし、レジ係が手動で数量を変更することは可能です。
数量を変更するたびに、セルを行の別のセルに置いたときにアイテムの価格の合計で合計価格が更新されるはずですが、それは発生せず、ソースは別の行に移動したときにのみ更新されます同じ行の別のセルではありません。
行ではなくセルが変更されたときに、DataGrid
にソースを更新させる方法はありますか?
はい、これは可能です。あなたの質問は基本的に DataGrid-編集動作の変更 と同じです
以下のコードは主にQuartermeisterの回答からのものですが、現在のセルが変更されたときにDependencyProperty
バインディングを更新する必要がある場合に設定できるDataGrid
BoundCellLevelを追加しました。
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;
}
}
}
各バインディングにUpdateSourceTrigger=LostFocus
を適用します。それは私にとって魅力のように機能しました。
<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
ItemContainerGenerator.ContainerFromItem(item)
からフェッチされた行がnullになり、ループが非常に遅くなるため、受け入れられた回答のコードは機能しませんでした。
質問に対するより簡単な解決策は、ここで提供されるコードです: 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;
}
}
アルムンドは正しい。 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"
を追加する必要があります。