How to determine if a row in ObservableCollection<T> actually changed

蓝咒 提交于 2019-12-24 02:16:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!