|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
PrerequisitesIn order to run the samples and follow the article, you must have Visual Studio 2005 and C# installed. IntroductionThe most convenient and advanced approach in working with data is to use business objects that encapsulate business logic. Then these objects make calls to the Data Access Layer to persist information. Business objects can be created by hand or generated by the ORM tool. Once we have the classes ready and hydrated (data is extracted from the persistence layer), we show objects in some grids and give the user the ability to edit objects in forms. So far so good. Thanks to Microsoft for the The ProblemAs a typical case, the user selects a single object from the grid and opens the form for editing. Modal form is shown and the business object's properties are bound to the form's controls. By using data binding, we are able to commit the changed data from controls to the object according to the
This gives us some control "when" the data source is updated. What if we want to discard changes? ResolutionsAt this point we have two solutions:
Generic IEditableObject implementationProvided here is a generic implementation which could easily be added to the base class and included in existing projects. This implementation preserves values for all public properties do not keep an eye on all fields, private properties, public properties without set ancestor First we need some Store original valuesThis is the flag that the object is in edit mode too. Hashtable props = null;
BeginEdit()This method stores the current values for future restoration using reflection. public void BeginEdit()
{
//exit if in Edit mode
//uncomment if CancelEdit discards changes since the
//LAST BeginEdit call is desired action
//otherwise CancelEdit discards changes since the
//FIRST BeginEdit call is desired action
//if (null != props) return;
//enumerate properties
PropertyInfo[] properties = (this.GetType()).GetProperties
(BindingFlags.Public | BindingFlags.Instance);
props = new Hashtable(properties.Length - 1);
for (int i = 0; i < properties.Length; i++)
{
//check if there is set accessor
if (null != properties[i].GetSetMethod())
{
object value = properties[i].GetValue(this, null);
props.Add(properties[i].Name, value);
}
}
}
CancelEdit()This method restores old values. public void CancelEdit()
{
//check for inappropriate call sequence
if (null == props) return;
//restore old values
PropertyInfo[] properties =(this.GetType()).GetProperties
(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < properties.Length; i++)
{
//check if there is set accessor
if (null != properties[i].GetSetMethod())
{
object value = props[properties[i].Name];
properties[i].SetValue(this, value, null);
}
}
//delete current values
props = null;
}
EndEdit()This method just deletes stored values (and our flag). public void EndEdit()
{
//delete current values
props = null;
}
|
||||||||||||||||||||||