Chapter 2 - Handling Data
Release Date: 8/20/2004
| Update Date: 8/20/2004
Intelligent client architecture and design guide
David Hill, Brenton Webster, Edward A. Jezierski, Srinath Vasireddy and Mohammad Al-Sabt, Microsoft Corporation; Blaine Wastell, Ascentium Corporation; Jonathan Rasmusson and Paul Gale, ThoughtWorks; and Paul Slater, Wadeware LLC
Related Links
Microsoft® Patternals & Practices Library http://www.microsoft.com/resources/practices/default.mspx
Application Architecture for .NET: Designing Applications and ServicesHttp: //msdn.microsoft.com/library/en-us/dnbda/html/distapp.asp
Summary: This chapter analyzes the various precautions when applying data in the client, including data cache, data concurrency, and data sets and Windows form data binding.
This page
Data type cache data data concurrently using the ADO.NET Dataset to manage data Windows Form Data Binding Summary
In the smart client, application data can be used on the client. It is important to make your intelligent client work effectively, and it is important to properly manage the data to ensure that it is effective, consistent, and safe.
Application data can be provided to the client through a server-side application (for example, through a web service), or the application can use its own local data. If the data is provided by the application, the smart client application can cache data to improve performance or support from offline. In this case, you need to decide how the client application should handle the data that has been out of the server.
If the intelligent client application provides the ability to modify the data locally, you must synchronize the client to the server-side application later. In this case, you must decide how the client application handles data conflicts and how to track changes to the server needs to be sent.
When you design your smart client application, you need to carefully consider these issues and many other questions. This chapter analyzes various considerations when processing data on the client, including:
• type of data. • Cache data. • The data is concurrent. • Use the ADO.NET dataset to manage data. • Windows Form Data Binding.
This chapter does not discuss many other issues related to processing data. Specifically, in Chapter 5: Safety Precautions discusses the data processing security issues, in Chapter 4: Occasionally, the offline consideration is discussed.
type of data
Intelligent clients usually have to handle data of two categories:
• Read-read reference data • Transient data
Typically, these types of data need to be processed in different ways, therefore analyze more types more useful in more detail.
Read-only reference data
The read-only reference data is not changed by the client and is used by the client to reference the destination. Therefore, from the viewpoint of the client, the data is read-only, and the client does not perform update, insert, or delete it. Read-only reference data is easy to cache on the client. Quote Data has many uses in smart client applications, including:
• Provide static references or find data. Examples of this include product information, price list, shipping options and prices. • Support data verification, allowing the user to enter the correctness of the data. Example has the date for checking the delivery schedule. • Help communicate with the remote service. Examples are locally selected to convert the user to the product ID and then send the information to the web service. • Present data. Examples include presentation help text or user interface tags. By storing and using reference data on the client, you can reduce the amount of data that needs to be transferred from the client to the server, help enable offline functionality and provide early data verification to increase the availability of the application.
Although the client cannot change read-only reference data, you can make changes on the server (for example, by administrator or superuser). You need to determine the policy to update the client when you have changed data changes. Such strategies may involve pushing changes to the client when changing, or pulling changes from the server before performing some operations on a specific time interval or on the client. However, because the data is read-only on the client, you do not have to track client changes. This simplifies the way to process read-only reference data.
Transient data
Transient data can be changed on a server or change on the client. Typically, transient data changes as direct or indirect results of user input and operation. In this case, the changes in the client or server need to synchronize at some point. This type of data has many uses in the intelligent client, including:
• Add new information. Examples include adding bank business transactions or customer details. • Modify existing information. Example Update customer details. • Delete existing information. Example Removes customers from the database.
One of the most difficult aspects of intelligent client processing transient data is that these data may be modified simultaneously on multiple clients. This problem will deteriorate when the data is very unstable because the changes are more likely to conflict with each other.
You need to track any client changes to the transient data. You should not think that transient data has been confirmed before synchronizing data with the server and resolves any conflict. You should be very careful to avoid important decisions on unrecognized data, or use this data as other local changes without serious consideration of how to ensure data consistency (even in synchronization failure).
For more information on processing data around offline, see Chapter 4: Occasionally connected smart clients.
Back to top
Cache data
Intelligent clients typically need to cache data locally (whether read-only reference data or transient data). By cache data, it is possible to improve the performance of the application and provide the data required to work offline. However, you need to carefully consider which data causing on the client, how to manage these data and use this data in which context can be used.
To enable a data cache, your smart client application should implement some form of cache infrastructure to transparency processing data cache details. Your cache infrastructure should include one or both of the following cache mechanisms:
• Short-term data cache. Cache data in memory is beneficial, but not lasting, so you may need to pull the data from the source when reruning the application. Doing so may hinder your application offline operation. • Long-term data cache. By cache data in persistent media such as independent storage or local file systems, you can use applications when you are not connected to the server. You can choose to combine long-term storage with short-term storage to improve performance.
No matter which caching mechanism you use, you should make sure that only the data that the user has access to the client. Moreover, the sensitive data requirements of the client cache are carefully handled to ensure its security. Therefore, you may need to encrypt data when transferring data to the client and store data on the client. For more information, see Chapter 5: Security Precautions.
When you design a smart client to support data cache, you should consider providing a mechanism for requesting new data regardless of the cache. This means you can make sure the application is always able to perform new transactions and will not use outdated data. You can also configure the client to get data in advance to reduce the risk of offline status when cache data expires. As long as it is possible, you should associate some form of metadata with the data to enable the client to manage this data in a smart manner. Such metadata can be used to specify the identity of the data and any constraint, or specify the desired behavior associated with the data. Your client cache infrastructure should consume this metadata and use it to properly process the cache data.
All the data of the client cache should be a unique identified (e.g., by version number or datestamp) to determine if it is necessary to update the data, the corresponding data can be correctly identified. In this way, your cache infrastructure can ask the server to be valid if the data it has, and determines if updating is needed.
Metadata can also be used to specify constraints or behaviors related to the use and processing of cache data. Examples include:
• Time constraints. These constraints specify the time or date range of cache data. When the data is outdated or expired, it can be discarded from the cache, or by obtaining the latest data from the server. In some cases, the appropriate approach may be to allow the client to use the timeout reference data, and the outdated data is mapped to the latest data when synchronizing with the server. • Geographic constraints. Some data may only apply to specific areas. For example, you may have a different price list for different locations. You can use your cache infrastructure to access and store data for different locations. • Safety requirements. Data supplied to a particular user can be given to ensure that only the corresponding user can access these data. In this case, the data provided has been encrypted, and the user must provide credentials to the cache infrastructure to decrypt the data. • Business Rules. You may have business rules associated with cache data to specify how to use them. For example, your cache infrastructure may consider the role of the user to determine which data is provided to the user and how to handle this data.
Your cache infrastructure can properly handle these data by metadata associated with data, so that your application does not have to care about data cache or implementation details. You can pass the metadata associated with these data inside the reference data itself, or you can use the external mechanism. The exact mechanism used to transfer metadata to the client depends on your application and network service. When using a web service, use the SOAP header to transfer metadata to the client is a good solution.
The difference between read-only reference data and transient data is sometimes meant to use two caches, one for reference data, one for transient data. The reference data is read-only on the client and does not need to go back to synchronize with the server, but it does need to refresh occasionally to refresh to reflect any changes and updates performed on the server.
Transient data can be changed on a server or change on the client. Since the data in the client is sometimes updated in the client, sometimes the server is updated, sometimes updated in these two locations, then changes to the client data need to be synchronized with the server at a time. If the data has changed on the server, a data conflict occurs, and it needs to be properly processed.
To help ensure that data consistency is maintained, avoid using data inappropriately, you should carefully track any changes to the client's transient data. Such changes are not submitted or tentative before successfully synchronizing or confirming with the server.
You should properly design your smart client application to distinguish between data that has successfully synchronized with the server and still tentably data. This distinction process can help applications easier to detect and process data conflicts. Moreover, you may need to prohibit application or users based on tentative data for important decisions or initiate important operations. You should not rely on them until you synchronize such data with the server. By using the appropriate cache infrastructure, the provisional data and the confirmed data can be tracked. Cache application block (CACHING Application BLOCK)
The cache application block is a Microsoft® .NET frame extension that enables developers to easily cache data from the service provider. The purpose of generating and designing It is to encapsulate Microsoft's suggested cache guidelines in the .NET framework application, such as at http://msdn.microsoft.com/library/en-us/dnbda/html/cachingarch.asp Caching ArchitectureCTure Guide for .NET Framework Applications described.
The overall architecture of the buffer block is shown in Figure 2.1.
Figure 2. Cache block workflow
The cache workflow contains the following steps:
1. The client or service agent issues a request to the cache data item to the CacheManager. 2. If the data item has been cached, CacheManager retrieves the item from the store and returns it as a CacheItem object. If the item has not been cached, the client will be notified. 3. After retrieving unacked data from the service provider, the client sends the data to the CacheManager. CacheManager adds a signature (ie, metadata) to the data item, such as a key, expiration time, or the like, and load it into the cache. 4. CacheService Monitor the survival of CacheItems. When cacheitem expires, CacheService will delete it and call the callback delegation according to the situation. 5. CacheService can also clear all data items from the cache.
The cache block provides a variety of cache expiration options as described in Table 2.1.
Table 2.1 Cache Block Expired Options
Class Description AbsoluteTime is used to set an absolute time of the expiration time. ExtendedFormatTime is used to set the expiration time based on expressions (such as Every MINUTE or EVERY MONDAY). FileDependency is used to set the expiration time based on whether the file is changed. SlidingTime is used to set the survival period of the item, and the method is based on the last access time of the item to specify the expiration time.
The following storage mechanisms can be used to use:
• Memory map (MMF). The MMF is best suited for client-based high-performance cache schemes. You can use MMF to develop a cache that can be shared between multiple applications and processes in the same computer. The .NET frame does not support MMF, any implementation of the MMF cache runs in the form of a non-host code, and does not benefit from any .NET framework, including memory management functions (such as garbage recycling) and security features (such as code Access security). • Singleton object. You can use the .NET remote to process the Singleton object to cache data that can be shared between processes in one or more computers. The method is to implement a cache service using a Singleton object that provides services to multiple clients via .NET remotely. Single-case cache implementations are simple, but it lacks performance and scalability provided by Microsoft SQL ServerTM solutions. • Microsoft SQL Server 2000 database. SQL Server 2000 storage is best suited for applications to have high perspective or you need to cache a large amount of data. Since the cache service needs to access SQL Server over the network, the speed of data access is relatively slower with the database query. • Microsoft SQL Server Desktop Engine (MSDE). MSDE is a light database replacement product of SQL Server 2000. It provides reliability and security features, but has a smaller client footprint than SQL Server, so it requires less settings and configuration. Since MSDE supports SQL, developers can get a lot of functions of the database. If necessary, you can migrate the MSDE database to the SQL Server database. Back to top
Data concurrency
As mentioned earlier, a problem using the smart client is that the data saved on the server may change before synchronizing any client changes with the server. You need to use a mechanism to ensure that the data collision can be properly processed when synchronizing the data, and the final data is consistent and correct. The data can be updated by multiple clients called "data concurrency".
You can use two ways to process data:
• Conservative concurrency. Conservative concurrency allows a client to keep the lock on the data to prohibit any other client to modify the data until the client's own changes are completed. In this case, if another client attempts to modify the data, these attempts will fail or blocked before the lock owner releases the lock. • Conservative concurrency may have problems, as a single user or client may remain locked for a long time due to negligence. So, the lock may prevent important resources (such as database lines or files) to be released in a timely manner, thus seriously affecting the scalability and availability of the application. However, when you need to completely control the changes made to important resources, conservative concurrency may be appropriate. Note that if your client wants to work offline, you cannot use this concurrent because the client cannot lock the data. • Open concurrent. Open concurrency does not lock the data. To determine if there is actually need to be updated, the original data can be sent with the update request and the changed data. Subsequently, the original data will be checked for the current data to see if the original data is updated. If the original data is matched, the update is executed; otherwise, the request is rejected, and an open failure is generated. To optimize this process, you can use a timestamp or update counter in the data without having to send raw data, and then you only check the timestamp or counter. Open concurrency provides a good mechanism that can be used to update primary data that is not very frequently changed, such as customer phone numbers or addresses. Open concurrent allows each person to read data, and the risk of open failure may be acceptable if the probability of the update is less than the reading operation. Open concurrency may not be appropriate in the case where data frequent changes and open updates may often fail. In most intelligent client scenarios, including the client to work offline, the open concurrency is the correct way because it allows multiple clients to use data at the same time without unnecessarily locking the data and affects all Other clients.
For more information on open and conservative concurrency, see "Optimistic Concurrence" in .NET Framework Developer's Guide, the URL is: http://msdn.microsoft.com/library/en-us/cpguide/html/cpconoptimisticConcurrency. ASP.
Back to top
Use the ADO.NET data set to manage data
DataSet is an object representing one or more relational database tables. The data set stores data in the cache that is disconnected. DataSets' Structure and Relational Database Similar: It discloses a hierarchical object model consisting of tables, rows, and columns. In addition, it also includes constraints and relationships defined by DataSets.
The ADO.NET DataSet contains a collection of a table composed of a table represented by a DataTable object. DataTable is defined in the System.Data namespace and represents a single table consisting of a single memory resident data. It contains columns represented by DataColumnCollection and a set of constraints represented by constraintCollection, which together define the architecture of the table. DataTable also includes a collection of rows represented by DataRowCollection (which contains data in this table). Together with the current state, Datarow retains its current version and the original version to identify changes made to the value stored in the row.
DataSets can be stronger or non-type. Type DataSet inherit from the DataSet base class, but a strong type of language function is added to the DataSet, allowing users to access content with more enhanced programming. Any type can be used when generating an application. However, Microsoft Visual Studio ® development systems have more support for Type DataSets, which make it easier to program with DataSets, and it is not easier to errors. DataSet is especially useful in intelligent client environments because they provide functions that help clients use data in offline. They can track local changes to data, which helps to synchronize data and coordinate data conflicts with server, and they can also be used to combine data from different sources.
For more information on how to use DataSets, see "Introduction to DataSets" in Visual Basic and Visual C # Concepts, URL: http://msdn.microsoft.com/library/en-us/vbcon/html/vbcondatasets.asp .
Merge data with DataSets
DataSet has the ability to merge DataSet, DataTable or DataRow objects to existing DataSets. This feature is especially useful for tracking changes made on the client and merge with the updated content of the server. Figure 2.2 shows a smart client updated from a web service request, and new data is returned as a data transfer object (DTO). DTO is a business model that allows you to package all data that needs to communicate with the web service into an object. Using DTO usually means you can make a single call for a web service instead of multiple calls.
Figure 2.2 By using the DataSets merged the data on the client
In this example, when the DTO is returned to the client, the DTO will be used to create a new DataSets in a local manner on the client.
Note After the merge operation, ADO.NET does not automatically change the status from Modified to Unchanged. Therefore, after the new DataSets is merged with the local client DataSets, you need to call the AccceptChanges method on DataSets to reset the ROWSTATE attribute to Unchanged.
For more information on how to use DataSets, see "Merging Dataset Contents" in .NET Framework Developer's Guide, the URL is: http://msdn.microsoft.com/library/en-us/cpguide/html/cpconmergingDataSetContents.asp.
Improve DataSets performance
DataSets typically contain a large amount of data, and if this data is passed over the network, it may result in performance issues. Fortunately, via ADO.NET Datasets, you can use the getChanges method on DataSets to ensure that only data changed in DataSets is transmitted between the client and the server, and package the data into the DTO. This data will then be merged into the DataSets of its destination.
Figure 2.3 shows a smart client that changes local data and uses the getChanges method on DataSets to submit only changed data to the server. For performance reasons, the data is transmitted to the DTO.
Figure 2.3 Improve performance using DTO
You can use the GetChanges method to use smart client applications that require offline work. When the app is renewered, you can use the getChanges method to determine which information has been changed, and then generate a DTO with the web service communication to ensure that the change is submitted to the database. Back to top
Windows Form Data Binding
Bind through the Windows Form Data, you can connect the user interface of the application to the base data of the application. Windows Forms Data Bind supports two-way binding, so you can bind the data structure to the user interface, display the current data value to the user, using the user to edit the data, and then automatically update the base data using the user input.
You can use Windows Forms Data Binding to bind almost any data structure or object to any properties of the user interface control. You can bind a single data item to a single property of the control, and you can bind more complex data (eg, data items or database tables) to the control so that it can be displayed in a data grid or list box. All data.
Note You can bind any objects that support one or more public properties. You can only bind to the public properties of the class rather than public members.
Binding via Windows Forms, you can provide flexible, data-driven user interfaces with your application. You can use data binding to provide custom controls for user interface appearance (for example, by binding to certain control properties, such as background or foreground color, size, image, or icon).
Data binding has many uses. For example, you can use it to complete the following tasks:
• Display read-only data to the user. • User users can update data from the user interface. • Provide a primary view of the data. • User users can browse complex related data items. • Provide lookup table features, enable user interfaces to connect user-friendly display names.
This section analyzes some of the features of the data binding and discusses some data binding functions that you often need to implement in your smart client application.
For more information on data binding, see "Windows Forms Data Binding and Objects", URL: http://msdn.microsoft.com/library/en-us/dnadvnet/html/vbnet02252003.asp.
Windows Form Data Binding Architecture
Windows Form Data Binding provides a flexible infrastructure for bidirement data bidirectional to the user interface. Figure 2.4 shows a schematic diagram showing the overall architecture of the Windows Form Data Binding.
Figure 2.4 Windows Form Data Binding Architecture
Windows Form Data Binds Use the following objects:
• data source. The data source is an object that contains data to be bound to the user interface. The data provider can be any object with public attributes, which can be an array or collection that supports an ILIST interface, or an example of a complex data class (for example, a DataSet or DataTable). • CurrencyManager. The CurrencyManager object is used to track the current location of the data bound to the user interface. Bind the data set to the user interface and navigate in the corresponding data, and update the user interface to reflect the currently selected items within the collection. • PropertyManager. The PropertyManager object is responsible for maintaining the current properties of the object that is bound to the control. The PropertyManager class and the CurrencyManager class are inherited from the public base class BindingManagerBase. All data providers that bind to the control have an associated CurrencyManager or PropertyManager object. • BindingContext. Each Windows Form has a default BindingContext object that tracks all CurrencyManager and PropertyManager objects on the corresponding form. The CurrencyManager or PropertyManager object of a specific data source can be easily retrieved via a BindingContext object. You can assign a specific BindingContext object to container controls that contain data binding controls (such as GroupBox, Panel, or TabControl). Doing so allows each part of the form being managed by its own CurrencyManager or PropertyManager object. • binding. Binding objects are used to create and maintain simple binding between the individual properties of the control with the properties of another object or the current object's properties of the current object. Bind data to Windows Form Controls
There are many properties and methods that can be used to bind to a specific Windows Form Control. Table 2.2 shows some of these more important properties and methods.
Table 2.2 Properties and Methods for Binding to Windows Form Controls
Properties or Method Windows Form Control Description DataSource Properties ListControls (for example, ListBox or Combo Box), the DataGrid control allows you to specify data provider objects to bind to user interface controls. Displaymember Properties ListControls allows you to specify a member of the data provider to display to the user. Valuemember Properties ListControls allows you to specify values associated with the display value for your application within your application. DataMber Properties DataGrid control If the data source contains multiple data sources (for example, if you specify a Datasets containing multiple tables), use the DataMber property to specify the data source to bind to the grid. (Refer to the note later.) SetDataBinding method DataGrid control allows you to reset the DataSource method at runtime.
Note If DataSource is a DataTable, DataView, a collection, or array, you do not need to set the DataMber property.
You can also explicitly add Binding objects to any control objects using the DataBindings collection properties provided on all Windows Form Controls objects. Binding objects are used to bind individual properties on the control to a single data member of the data provider. The following code example adds a binding between the text attribute of a text box control and a customer name in the Customers table of a dataset.
TextBox1.DataBindings.add (
New Binding ("Text", DataSet, "Customers.customername")); When you build a binding example with a binding constructor, you must specify the name, data source, and resolution of the control attribute to be bound to the data source. A navigation path of the list or attribute. The navigation path can be a native string, a single attribute name, or a name hierarchy separated. You can use the hierarchical navigation path to navigate in the data tables and relationships in the DataSet object, or navigate to the object model of the object to other objects in the object's properties. If you set the navigation path to an empty string, the toString method is called on the underlying data source object.
Note If the attribute is read-only (ie, the object does not support setting operations to this property), the data binding will not make the bound Windows Form Control to read only by default. This may bring confusion to the user because the user can edit the value in the user interface, but the value in the binding object will not be updated. So, make sure that all the read-only flags of the Windows Form Control that are bound to read-only properties are set to True.
Bind the control to DataSets
It is usually useful to bind controls to data sets. Doing so allows you to display dataset data in a data grid and make users easily update data. You can use the following code to bind the data grid control to the DataSet.
DataSet newDataSet = WebServiceProxy.getDataSet ();
This.DataGrid.SetDataBinding (NewDataSet, "TableName");
Sometimes you need to replace the contents of the dataset after all bindings have been established with your control. However, all bindings will still point to the old data set when replacing the existing collection with a new collection.
Has a better way to manually recreate data bindings with new data sources is that you can use the DataSet class's MERGE method to import the data in the new data set into an existing dataset, as shown in the following code example.
DataSet newDataSet = myservice.getdata ();
THIS.DATASET1.CLEAR ();
This.dataset1.merge (NewDataSet);
Note To avoid threaded problems, you should only update the bound data objects on the UI thread. For more information, see Chapter 6: Using multiple threads.
Navigate in the data collection
If your data source contains an item collection, you can bind the data to the Windows Form Control, and navigate item-by-item. The user interface will automatically update the current item in the collection.
You can bind to any collection objects that support the ILIST interface. When you bind to an object collection, you can let the user navigate each item in the collection and automatically update the user interface of each item. Many collections and complex data classes provided by .NET Framework have supported an ILIST interface, so you can easily bind to array or complex data, such as data rows or data views. For example, any ILIST interface is implemented by an array object as an instance of the System.Array class, thus being bound to the user interface. Many ADO.NET objects also support ILIST interfaces or its derived interfaces, so that these objects can also be easily binded. For example, DataViewManager, DataSet, DataTable, DataView and DataColumn classes support data binding in this way.
A data source that implements the ILIST interface is managed by the CurrencyManager object. This object maintains the index of data sets through its Position property. This index is used to ensure that all controls are bound to all controls in the data source read / write data sets.
If your form contains controls that are bound to multiple data sources, it will have multiple CurrencyManager objects, respectively correspond to individual independent data sources, respectively. The BindingContext object provides convenient access to all CurrencyManager objects on the form. The following code example shows how to increment the current location within the Customers collection. This.BindingContext [DataSet, "Customers"] .position = 1;
You should use the COUNT property on the CurrencyManager object as shown in the following code example to ensure that the invalid position is not set.
IF (this.BindingContext [DataSet, "Customer"] .Position <
(this.bindingcontext [dataset, "customer"] .count - 1))
{
This.BindingContext [DataSet, "Customers"] .position = 1;
}
The CurrencyManager object also supports the PositionChanged event. You can create the handler of the event so that your user interface is updated to reflect the current binding position. The following code example shows a label to illustrate the current position and the total number of records.
this.bindingContext [DataSet, "Customers"] .positionchanged =
New EventHandler (this.BindingPensionChange);
The implementation of the method BindingPositionChanged is as follows.
Private void BindingPositionChanged (Object Sender, System.Eventargs E)
{
PositionLabel.Text = String.Format ("Record {0} of {1}",
This.BindingContext [dspus1, "authors"]. Position 1,
This.BindingContext [DSPUBS1, "Authors"]. count);
}
Custom format and data type conversion
You can use the Binding class Format and Parse events to provide custom formats for data binding to the control. Through these events, you can control the way the data is displayed in the user interface and how to obtain data and analysis data from the user interface to update the base data. You can also use these events to convert data types so that source data types are compatible with target data types.
Note If the data type of the binding attribute on the control does not match the data type of the data in the data source, an exception is triggered. If you need to bind an incompatible type, you should use the Format and Parse events on the Binding object.
When reading data from the data source and displays it in the control, the Format event will occur when the data is read from the control and use it to update the data source. When data is read from the data source, the Binding object will use the Format event to display formatted data in the control. The Binding object will use the Parse event when you read the data from the control and use it to update the data source.
Format and Parse events allow you to create a custom format for displaying data. For example, if the type of data in the table is DECIMAL, you can display data locally by setting the Value property of the ConvertEventArgs object to the format value in the Format event. Therefore, you must format the displayed value in the Parse event.
The following code example binds the order amount to the text box. Format and Parse events are used to convert between String types desired by text boxes and Decimal types desired by the data source. Private void BindControl ()
{
Binding binding = new binding ("text", dataset,
"Customers.custtoorders.OrDeramount");
// add the delegates to the event.
Binding.format = New ConvertocurrencyString;
Binding.Parse = New ConvertEventHandler (CurrencyStringTodecimal);
Text1.databindings.add (binding);
}
Private void Decalog (Object Sender, ConvertEventArgs CEVENT)
{
// The method Converts Only to string type. Test this using
DesiredType.
IF (CEVENT.DESIREDTYPE! = TypeOf (string)) Return;
// use the torstring method to format the value as currency ("c").
CEVENT.VALUE = ((decimal) CEVENT.VALUE). Tostring ("C");
}
Private Void CurrencyStringTodecimal (Object Sender, ConvertEventArgs CEVENT)
{
// The Method Converts Back to Decimal Type ONLY.
IF (CEVENT.DESIREDTYPE! = TypeOf (Decimal)) Return;
// Converts The String Back to Decimal Using The Static Parse Method.
CEVENT.VALUE = Decimal.Pars (Cevent.Value.toString (),
NumberStyles.currency, NULL);
}
Use model-view-controller mode to implement data verification
By binding the data structure to the user interface element, the user can edit the data and ensure that the changes are changed back to the underlying data structure. Typically, you need to check the user's changes to the data to make sure the input value is valid.
The Format and Parse events described in the previous section provide a way to intercept the user's changes to the data so that the data is valid. However, this method requires data verification logic with custom format code (usually in the form level). If you implement these two responsibilities in the event handler, you will make your code difficult to understand and maintain.
A more elegant approach is to design the code to use the model-view-controller (MVC) mode. This mode provides nature separation of various responsibilities involved in editing and changing data through data binding. You should implement a custom format within a form responsible for rendering data in a specific format, and then associates the verification rule with the data itself to reuse these rules in multiple forms.
In the MVC mode, the data itself is packaged in the model object. The view object is the Windows Form Control that the data is bound. All changes made to this model are processed by an intermediate controller object, which is responsible for providing access to data and is responsible for controlling any changes made through view objects. The controller object provides a natural location for verifying changes to the data, and all user interface verification logic should be implemented here. Figure 2.5 depicts the structural relationship between three objects in the MVC mode.
Figure 2.5 Model - View - Objects in Controller Mode
There are many advantages to using the controller object in this way. You can configure a normal controller to provide custom authentication rules that can be configured in accordance with certain context information (eg, user roles) at rules. Alternatively, you can also provide many controller objects, each controller object implements a specific verification rule, then select the appropriate object at runtime. Regardless of the way, all verification logic is packaged in the controller object, so the view and model objects do not need to be changed.
In addition to separating data, authentication logic, and user interface controls, the MVC model provides you with a simple way to automatically update user interfaces when basic data changes. The controller object is responsible for notifying the user interface when changing the data over other programming means. Windows Form Data Binds Listen to events generated by objects that are bound to controls so that the user interface can automatically respond to changes made by underlying data.
To implement an automatic update of the user interface, you should make sure that the controller implements a change notification event for each possible changes. Event should follow naming conventions
The following code example defines a Customer object that implements the NAME property. The CustomerController object processes the authentication logic of the Customer object and supports the Name property, and the attribute represents the Name property on the base Customer object. This controller will inspire an event whenever the name changes.
Public Class Customer PUBLIC CLASS CUSTOMER
{
Private string _name;
Public customer (String name) {_name = name;
Public String Name
{
Get {return _name;}
Set {_name = value;}
}
}
Public Class CustomerController
{
Private customer_customer = null;
Public Event EventHandler NameChanged;
Public Customer (Customer Customer)
{
THIS._CUSTOMER = Customer;
}
Public String Name
{
Get {return_customer.name;}
set
{
// Todo: Validate New Name to make Sure It is valid.
_CUSTOMER.NAME = VALUE;
// Notify Bound Control of Change.
IF (NameChanged! = null)
NameChanged (this, eventargs.empty);
}
}
}
Note The Customer Data Source member needs to initialize when declaring. In the previous example, you need to initialize the Customer.name member to an empty string. This is because before the data binding occurs, the .NET framework does not have the opportunity to interact with the object and set the default empty string settings. If the Customer data source member is not initialized, the runtime exception is caused when the value is retrieved from the variable that is not initialized. In the following code example, the form has a TextBox object TextBox1, which needs to be bound to the name of the customer. The code binds the Text property of the TextBox object to the Name property of the controller.
_CUSTOMER = New Customer ("Kelly Blue");
_Controller = New CustomerController (_CUSTOMER);
Binding binding = new binding ("text", _controller, "name");
TextBox1.databindings.add (binding);
If you change the customer's name (using the Name property on the controller), the NameChanged event will be fired and the text box is automatically updated to reflect the new name value.
Update the user interface when the basic data change
You can automatically update the user interface when you use the Windows Form Data Binding to automatically update the user interface. This task can be done by implementing a change notification event on the binding object. Change Notification Events are named after the following agreements.
Public Event EventHandler Changed;
Therefore, suppose you bind the Name property of an object to the user interface, then the name of the object changes due to some processing, then you can update the user interface by implementing the NameChanged event on the binding object to reflect The new Name value.
Back to top
summary
In determining how many different considerations are involved in how to process data in smart clients. You need to determine if you cache and how to cache your data, and determine how to handle data concurrency. You will often decide to use the ADO.NET dataset to process your data, and you may also decide to utilize the Windows Form Data Binding.
In many cases, read-only reference data and transient data need to perform different processing. Because smart customers typically use these two types of data, you need to determine the best way to handle each category data in your application.
Go to the original English page
Back to top