I encountered such a problem in a recent project (winform) and faced with the problem statement below:
The interface of a certain wage calculation module is very complex. Eight DataGrid and eight dataset are bound respectively, and there are a lot of textbox associated with the data in the other two dataset. Update the data in a certain area of the interface. The data in other data sources varies accordingly. I don't want to talk about the design of requirement analysis. Under such a complicated UI, I am worried about data synchronization. During the recent test, an inexplicable error occurred, and the error source could not be found. It was almost depressing to death! The main reason is that in some cases, data becomes out of sync, and the monkey test cannot be handled at all (the interface is messy). Sadly, we are determined to rewrite the key part.
During the rewriting process, I found an important problem: The logic of the control interface and the logic for processing business data should be independent. Even if the data displayed on the interface is incorrect, the actual data is still balanced.
For example, in the DataGrid, A cellvalue ranges from 10 to 100, and the difference value (New Value and old value subtract) is 90. We need to synchronize other data based on this difference.
First, the question is how to get the difference value. First, my practice is: DataGrid provides an event: validatingeditor. This event provides a verification before the new value is input to the data source. here we can use the new value in eventargs to compare with the current value to get the difference. If the difference value meets the requirements (business logic), update the difference value to each data source to maintain data synchronization. If the difference value does not meet the requirements, an error message is displayed and the original value is restored. At first glance, there are no problems, and the logic is clear. Do you think so?
During the test, the problem occurs. After a new value is entered, "other data sources" are also synchronized. However, when you look back, the old value is still the old value, the new value is not filled in the "current data source", why? After looking for a long time, although we finally found out the problem lies in the control itself, how can we fundamentally prevent such problems?
For the above example, when we find the difference value to synchronize data, it is written on the validatingeditor event. If some unexpected exceptions occur during the processing of this event (may be caused by the control itself or by ourselves), it will cause data errors. Therefore, the following transformations were made:
Considering that if validatingeditor is successfully verified, A cellvaluechanged event will inevitably be triggered. Here we can be sure that the data source is changed. Therefore, validatingeditor is only responsible for data verification and error message prompts. If the verification fails, cellvaluechanged will not be thrown. If the verification succeeds, the difference value is obtained in the event cellvaluechanged to synchronize various data sources. Note: When getting the difference value, try No Obtain the value provided by the control (obtained from eventargs above), and DirectSlave Data source itself The data balance is guaranteed here. In this way, I get the difference value (a row of dataset ):
Decimal V = ( Decimal ) Pdrow [ " Paymoney " , Datarowversion. Proposed] - ( Decimal ) Pdrow [ " Paymoney " , Datarowversion. Current];
Here, even if the Data Display error is caused by a control issue, the actual data is correct (balanced ). After the synchronization is complete, call:
Datagridview. updatecurrentrow ();
The interface is consistent with the data source. The above may be a special case, but I think this should be done in principle. I hope you will be inspired .~ ^