问题
I have an ObservableCollection
private static CertOrigin_Entities db = new CertOrigin_Entities(); private static ObservableCollection ocSHIPPING_DTL;
I have a WPF Datagrid that I do late binding on
private void btn_SEARCH_Click(object sender, RoutedEventArgs e)
{
string sCI = this.txt_SEARCH.Text;
var sd = (db.TBL_SHIPPING.Where(x => x.CommercialInvoiceNumber == sCI)).ToList();
if (sd.Count() > 0)
{
iID = (int)sd[0].SHIPPING_ID;
var query = (db.v_wpf_cert_origin.Where(x => x.SHIPPING_ID == iID));
ocSHIPPING_DTL = new ObservableCollection<v_wpf_cert_origin>(query.ToList());
dgCOO.ItemsSource = ocSHIPPING_DTL;
var cust = (from x in db.TBL_CUSTOMER
join y in db.TBL_REQUISITION on x.CUSTOMER_ID equals y.CUSTOMER_ID
join z in db.TBL_SHIPPING on y.REQ_ID equals z.REQ_ID
where z.SHIPPING_ID == iID
select new {CUST = x.CustomerName}).ToList();
this.lbl_CUSTOMER.Content = cust[0].CUST.ToString();
}
}
I am updating the SQL server database behind a button and on the window close
private static bool _SaveChanges()
{
DbTransaction _dbTransaction = null;
db.Connection.Open();
using (_dbTransaction = db.Connection.BeginTransaction())
{
try
{
db.SaveChanges();
db.AcceptAllChanges();
_dbTransaction.Commit();
db.Connection.Close();
}
catch (TransactionAbortedException ex)
{
db.Connection.Close();
throw ex;
}
return true;
}
}
Here is what is happening to me... In my datagrid, I have a textbox
<DataGridTemplateColumn Header="Hs Tarriff Class #:" Width="125" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=HsTarriffClassNumber,
UpdateSourceTrigger=PropertyChanged,
NotifyOnTargetUpdated=True}"
Name="txt_HsTarriffClassNumber"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
If the text box has 5864.193.45 as the value and I change it to 5864.193.46 then back to 5864.193.45 the ObservableCollection saves the record as the record did change, however I do not want it to save the record as it did not change.
The primary issue of the change is this. I have 3 triggers on the table
1 - After update Audit trigger that takes the deleted and inserts it into another database
2 - After Update Audit trigger that sends an email to a multidude of people stating that the user changed the data and they need to reprint the paperwork and send it to customs
3 - On Update trigger that updates a different table and sets the last_used_tarrif field equal to the value the user changed.
If the user did not actually change the data none of the above should fire. Is there a way to check if the record actually changed?
Can I compare the records in the observable collection to the records in the table and only update those that are actually different?
Any advice?
回答1:
Because you have the UpdateSourceTrigger set to PropertyChanged (see MSDN: Binding.UpdateSourceTrigger, every time it detects a change, it will action a change.
Changing from 5864.193.45 to 5864.193.46 is one action, then 5864.193.46 to 5864.193.45 is another action.
Process 1:
You could also change UpdateSourceTrigger to LostFocus (UpdateSourceTrigger=LostFocus
), this makes it so that the change doesn't get actioned until you click somewhere else. This way when you change from 5864.193.45 to 5864.193.46 , then 5864.193.46 to 5864.193.45 it wouldn't action the change until you leave that text area.
Process 2: You could always implement a master ObservationCollection and then only compare when you call _SaveChanges().
回答2:
Ok found an interesting item
private void dg_VQ_TABLE_VIEW_FocusedRowChanged(object sender, DevExpress.Xpf.Grid.FocusedRowChangedEventArgs e)
{
int rHANDLE = dg_VQ_TABLE_VIEW.FocusedRowHandle;
//if (rHANDLE == dg_VQ_DTL_TABLE_VIEW.NewItemRowData.RowHandle.Value) { return; }
_sync_child(rHANDLE);
}
When I select an item in the list box the Table View of the Data Grid fires the Row changing.
So I added a boolean, and now the problem is gone.
private void lst_REQ_LIST_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lst_REQ_LIST.SelectedValue == null) { return; }
_selection_changed();
bln_CHANGING_REQ = false;
}
private void _selection_changed()
{
string sGUID = lst_REQ_LIST.SelectedValue.ToString().ToUpper();
req_guid = new Guid(sGUID);
quote_guid = new Guid("{00000000-0000-0000-0000-000000000000}");
bln_CHANGING_REQ = true;
_load_data();
}
private void dg_VQ_TABLE_VIEW_FocusedRowChanged(object sender, DevExpress.Xpf.Grid.FocusedRowChangedEventArgs e)
{
if (bln_CHANGING_REQ) { return; }
int rHANDLE = dg_VQ_TABLE_VIEW.FocusedRowHandle;
//if (rHANDLE == dg_VQ_DTL_TABLE_VIEW.NewItemRowData.RowHandle.Value) { return; }
_sync_child(rHANDLE);
}
来源:https://stackoverflow.com/questions/12710787/how-to-determine-if-a-row-in-observablecollectiont-actually-changed