CHAPTER 8 ■ SQL AZURE 283 As I mentioned, there are two XML schemas that have been defined, SQLParameter.xsd and SQLDatabaseAccess.xsd, therefore we have corresponding UI components identified as ParameterControl and SQLDataServiceControl. Now let us have a close look at how this approach tremendously simplified the UI design and development for an application such as SQLAzureConnect. ParameterControl The UI layout of the ParameterControl is shown in Figure 8-20, and the implementation is shown in Listing 8-15. A parameterized constructor has been added to this user control. The parameterized constructor accepts the XML data object SQLParameterRoot (marked as a reference type) and the instance of the parent form (used to display the message back to the parent form). A BindingSource component is defined in this control and has been bound to the instance of the XML data object with the type of XML schema SQLParameter in the constructor of the user control as shown in the Listing 8-15. Figure 8-20. UI layout of the user control ParameterControl Listing 8-15. Implementations for ParameterControl using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; namespace SQLAzureConnect { using SQLAzureConnect.Schema.SQLParameter; public partial class ParameterControl : UserControl { private FormSQLAzureConnect parentForm = null; public SQLParameterRoot sqlParameter = null; public ParameterControl() { InitializeComponent(); } public ParameterControl(ref SQLParameterRoot sqlParameter, FormSQLAzureConnect parentForm) CHAPTER 8 ■ SQL AZURE 284 { InitializeComponent(); this.bindingSource.DataSource = sqlParameter = sqlParameter; parentForm = parentForm; UpdateUI(); } public void Add(SQLParameterRoot sqlParameter) { this.bindingSource.Add(sqlParameter); } public void DoDataExchange() { sqlParameter.Parameter.Value = this.txtValue.Text.Trim(); sqlParameter.Parameter.Size = this.txtSize.Text; sqlParameter.Parameter.Type = this.comboBoxType.SelectedItem.ToString(); if (radioButtonIn.Checked) { sqlParameter.Parameter.Direction = SQLParameterRootParameterDirection.In; } else if (radioButtonOut.Checked) { sqlParameter.Parameter.Direction = SQLParameterRootParameterDirection.Out; } else if (radioButtonInOut.Checked) { sqlParameter.Parameter.Direction = SQLParameterRootParameterDirection.InOut; } else if (radioButtonReturn.Checked) { sqlParameter.Parameter.Direction = SQLParameterRootParameterDirection.ReturnValue; } } private void UpdateUI() { if (null != sqlParameter) { this.txtValue.Text = sqlParameter.Parameter.Value; this.txtSize.Text = sqlParameter.Parameter.Size; this.comboBoxType.SelectedIndex = comboBoxType.Items.IndexOf( sqlParameter.Parameter.Type); switch ( sqlParameter.Parameter.Direction) { case SQLParameterRootParameterDirection.Out: this.radioButtonOut.Select(); break; case SQLParameterRootParameterDirection.InOut: CHAPTER 8 ■ SQL AZURE 285 this.radioButtonInOut.Select(); break; case SQLParameterRootParameterDirection.ReturnValue: this.radioButtonReturn.Select(); break; case SQLParameterRootParameterDirection.In: default: this.radioButtonIn.Select(); break; } } } private void ParameterControl Leave(object sender, EventArgs e) { DoDataExchange(); } } } For this user control and all other user controls following we use a BindingSource control to bind and synchronize the data object with the data that was edited by the user. This component comes with Visual Studio and can be found from the Toolbox pane under the Data category as Figure 8-21 shows. Figure 8-22 shows how to set up the property of the component after dragging it from the toolbox onto the user control design surface. Figure 8-21. Drag and drop the BindingSource component from Visual Studio Toolbox data pane to the ParameterControl design surface CHAPTER 8 ■ SQL AZURE 286 Figure 8-22. A BindingSource of ParameterControl is defined to bind the data source to the data object instance’s XML SQLParameterRoot When the instance of SQLParameterRoot has been accepted, the values of the element and attribute will be updated to the UI component via the private method call to UpdateUI(). When the control loses focus, the updated value modified by the user will be synchronized back to the XML data object via the method DoDataExchange(). The access to DoDataExchange() method is marked as public so that the parent host control can force a data refresh if necessary. SQLDataServiceControl The UI layout of the user control SQLDataServiceControl is shown in Figure 8-23, and the data binding source is defined to bind the data to the SQLDatabaseAccessRootSqlDataService as shown in Figure 8-24. The implementation of this user control is similar to that of ParameterControl. As with ParameterControl there are two methods, UpdateUI() and DoDataExchange(), defined in this class that are used to handle UI updating and data synchronization. Since this control is the host control of Parameter controls, this control is responsible for handling the adding and deleting of the underlying Parameter controls and forcing data synchronization when this control loses focus or when a data synchronization request is received from the parent form. These tasks are handled in the methods AddPage() and btnAddParameter Click(). Listing 8-16 shows the implementation for the user control SQLDatabaseAccess. CHAPTER 8 ■ SQL AZURE 287 Figure 8-23. UI layout of the user control SQLDataServiceControl Figure 8-24. A BindingSource of SQLDataServiceControl is defined to bind the data source to the data object instance’s XML SQLDatabaseAccessRootSqlDataServiceRoot Listing 8-16. Implementation for SQLDatabaseAccessControl using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; . using System.Drawing; using System.Data; using System.Linq; using System.Text; using System .Windows. Forms; namespace SQLAzureConnect { using SQLAzureConnect.Schema.SQLParameter; . using System.Drawing; using System.Data; using System.Linq; using System.Text; using System .Windows. Forms;