Unveil the Data Binding Architecture inside Microsoft ASP.NET Ajax 1.0 - Part 2
 
Published: 08 Jun 2007
Abstract
This article examines the practical usage associated with the client-side data binding techniques of the toolkit by building two distinct and more complex samples with the data sources derived from web services and a SQL Server 2005 database respectively.
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 32792/ 43

Introduction

In part 1, we mainly examined the data binding architecture inside Microsoft ASP.NET Ajax 1.0 in theory and gave a simple example. Now in part 2 we will continue to study the practical usage associated with the client-side data binding techniques of the toolkit, i.e. we will build two distinct and more complex samples with the data sources derived from web services and a SQL Server 2005 database respectively.

Look back to the sample in part 1

To familiarize you with plenty of controls and concepts concerning data binding on the client side, we have constructed a simple and integrated sample - AJAXCTPDev311. Let us summarize the important features with it.

·         It provides an integrated framework to create the basic MS AJAX data binding applications.

·         To create the website we have chosen to use the "ASP.NET AJAX CTP-Enabled Web Site" template; however, you can also use the common "ASP.NET AJAX-Enabled Web Site" template, but you have to add the assembly Microsoft.Web.Preview.dll (supporting xml-script programming and data binding) manually.

·         Whatever kinds of MS AJAX applications you are to create, the ScriptManager control plays the core role of whole AJAX architecturefrom the client side to the server side. In general, we should explicitly specify the web service related *.asmx files and the assemblies we use. Here we again list this related piece of code.

Listing 1

<asp:ScriptManager ID="ScriptManager1" runat="server" >
  <Services>
    <asp:ServiceReference Path="BookDataService.asmx" />
  </Services>
  <Scripts>
  <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" />
  </Scripts>
</asp:ScriptManager>

·         The ListView (and ItemViewto be used in the third sample) control has several templates, which are in turn associated with a set of div elements which may contain most of the basic HTML elements such as button, textbox, span, hyperlink, etc. Altogether to use ListView and ItemView, you have to earnestly analyze and grip the relationships between the templates and the div elements.

·         The declarative mode is a new and good approach of programming on the client side, which is to be studies in the next section.

·         The following diagram reveals the relations among the several key components we used.

Figure 1: The different data form transferred between the key components

Note here: First, the data form transferred among ListView, DataSource and WebService are different; second, the WebService generally provides data from databasesthe rectangle with broken lines here only means we have not used this form (to be examined in the third sample later on).

·         We have used a special kind of WebServiceDataService to provide data to ListView from the server side.

·         We have used the methods of WebService directly from the client side, have not we? This is a great change MS AJAX has brought to us.

Now, let us look more closely at the declarative mode with xml-script.

Introduction to the declarative programming in ASP.NET Ajax 1.0

Besides the direct JavaScript programming mode, ASP.NET AJAX provides another way to instantiate client-side typesdeclarative programming mode. Please take notice that to use the xml-script feature you must download the Futures CTP package from the Microsoft Ajax website and add a reference to the PreviewScript.js file contained in the Microsoft.Web.Preview assembly. For more detailed study on the declarative programming model under the lately ASP.NET AJAX 1.0, please refer to Alessandro Gallo's excellent series of tutorial on xml-script declarative programming from here. But note that this tutorial has just scratched the surface of xml-script programming, so to grasp this approach of programming you have to study almost every detail of the excellent exampleTaskList Microsoft has provided and even analyzed the xml-script grammar resolver inside file PreviewScript.js.

Therefore, we merely outline the basic steps when using the declarative mode, while let the code snippet anywhere in this series tell you the practical usage.

1.    Design your web pages as usualdefine the HTML elements.

2.    Create the MS AJAX client-side controls associated with these HTML elements.

3.    Manipulate these MS AJAX client-side controls to control the corresponding HTML elements indirectly.

To make declarative programming much easier, MS AJAX has not only introduced many client-side controls (such as Label, Button, InputControl, TextBox, Image, HyperLink, CheckBox, Select, ItemView, ListView, etc.), but also created a few advanced concepts (such as action, behavior, data binding, etc.).

In my opinion, the declarative mode comes into practice at least due to two important things: 1. to simplify the pure JavaScript programming by configuring the needed xml elements or tags and 2. to adapt to the future programming modeseparating the design from the implementation to facilitate development, as well as simplify the course of maintenance, updating, internalization, third-party development, compilation, and deployment, etc. While there exists these strong points with the xml-script declarative mode, from another point of view, this kind of script based on the XML schema makes debugging much more difficult. When I debug the samples I have to resort to the source code of the framework to find the bugs with little help from the error messages displayed. In some degree, this means you have to be familiar with the inner workings of the frameworktoo difficult for common programmers. Moreover, now there does not exist debugging tools to step into the declarative part of xml.

Sample 1 - binding a HTML ListView control to a Web Service

Please first note that there are many similarities in the example introduced here with the first one in Part 1; however, we will lay emphasis on the other aspects not yet mentioned previously. Now, you can start Visual Studio 2005 and still select the "ASP.NET AJAX CTP-Enabled Web Site" template to create a new website and name it ListEmployees. The following Figure shows its design-time snapshot.

Figure 2: The design-time sample web page

In this sample we will still use a ListView control to display an employee list, which is automatically executed when the page has been loaded completely. Now, let us follow the steps explained above to work.

1. Design the web page

Listing 2

//……omitted
    <link rel="stylesheet" type="text/css" href="site.css" />
    //……omitted
            <span style="font-size: 24pt; color: #6600cc">
                <strong>Employee Info Searching Results:</strong>
            </span>
            <div id="header">
                <span >
                <strong>EmpID</strong> &nbsp;
                </span>
               <span >
                <strong>Name</strong> &nbsp;
                </span>
                <span>
                <strong>Address</strong>
                </span>
            </div>
            <hr style="width: 457px" align="left" />
 
            <div id="searchResults">
            </div>
            <div style="visibility:hidden;display: none;">
                  <div id="searchResults_layoutTemplate">
                        <div id="searchResults_itemTemplate" >
                         &nbsp; &nbsp;<span id="searchResults_ID"></span> &nbsp;&nbsp;&nbsp;&nbsp;
                        <span id="searchResults_Name"></span>&nbsp;&nbsp;
                        <span id="searchResults_Address"></span>
                      </div>
                    <div id="searchResults_separatorTemplate" class="TaskSeparator">
                    </div>
                  </div>
                <div id="NoDataTemplate">Waiting...</div>
            </div>    

Here, we first create a constant header line within a div block to elegantly list the employee records below. Then starting from the line in bold, we construct the HTML elements in relation to each possible template of the advanced MS AJAX client-side controlListView. Here we have also used the separatorTemplate template to separate the neighboring records. As mentioned in Part 1, control ListView shows records in the AJAX way. So here we have also used the emptyTemplate templateNoDataTemplate so that when data from the WebService is being loaded the user can get a friendly hint.

2. Create the corresponding MS AJAX client-side controls

Here, mainly one MS AJAX client-side control, ListView, is created to match the HTML elements (mainly a set of divs), with its each template in correspondence with different div elements. Additionally, we have also defined three label elements matching the three span elements above.

Create the Web Service

Right click the project and choose "Add new item" and create a new Web Service named EmployeeDataService.asmx. Here, we have also made the Web Service derived from DataService, and then we have created four CRUD WebMethods. Listing 3 shows the crucial code snippet.

Listing 3

//……
using System.ComponentModel;
using System.Web.Script.Services;
using Microsoft.Web.Preview.Services;
//……
[ScriptService]
public class EmployeeDataService: DataService
{
  static List < Employees > _data;
  static int _nextId;
  static object _dataLock = new object();
  private static List < Employees > Data
  {
    get
    {
      if (_data == null)
      {
        lock(_dataLock)
        {
          if (_data == null)
          {
            _data = new List < Employees > ();
            _data.Add(new Employees(0, "John Smitch""1970 Napa Ct."));
            _data.Add(new Employees(1, "Mary Smitch""9833 Mt. Dias Blv."));
            _data.Add(new Employees(2, "Mike Jodan""7484 Roundtree Drive"));
            _data.Add(new Employees(3, "Ronald Adina""9539 Glenside Dr"));
            _data.Add(new Employees(4, "Blue Yonder Airlines""1226 Shoe St."))
              ;
            _data.Add(new Employees(5, "Milton Albury""1399 Firestone Drive"))
              ;
            _data.Add(new Employees(6, "Phyllis Allen""5672 Hale Dr."));
            _data.Add(new Employees(7, "Stanley Alan""6387 Scenic Avenue"));
            _data.Add(new Employees(8, "Alexander Berger""8713 Yosemite Ct."))
              ;
            _nextId = 9;
          }
        }
      }
      return _data;
    }
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Delete)]
  public void DeleteRecords(int id)
  {
    foreach (Employees row in _data)
    {
      if (row.Id == id)
      {
        lock(_dataLock)
        {
          _data.Remove(row);
        }
        break;
      }
    }
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Select)]
  public Employees[]SelectRecords()
  {
    return EmployeeDataService.Data.ToArray();
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Insert)]
  public Employees InsertRecords(string name, string Address)
  {
    Employees newRow;
    lock(_dataLock)
    {
      newRow = new Employees(_nextId++, name, Address);
      _data.Add(newRow);
    }
    return newRow;
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Update)]
  public void UpdateRecords(Employees updateRow)
  {
    foreach (Employees row in _data)
    {
      if (row.Id == updateRow.Id)
      {
        row.Name = updateRow.Name;
        row.Address = updateRow.Address;
        break;
      }
    }
  }
}
 
public class Employees
{
  private int _id;
  private string _name;
  private string _address;
  [DataObjectField(truetrue)]
  public int Id
  {
    get
    {
      return _id;
    }
    set
    {
      _id = value;
    }
  }
  [DataObjectField(false)][DefaultValue("")]
  public string Name
  {
    get
    {
      return _name;
    }
    set
    {
      _name = value;
    }
  }
  [DataObjectField(false)][DefaultValue("")]
  public string Address
  {
    get
    {
      return _address;
    }
    set
    {
      _address = value;
    }
  }
  public Employees()
  {
    _id =  - 1;
  }
  public Employees(int id, string name, string address)
  {
    _id = id;
    _name = name;
    _address = address;
  }
}

Here, for simplicity, we have used an in-memory data source, a static Array with basic element being Employees object to simulate the web service with states; while in enterprise development this is not a good habit.

Next, let us dwell upon the mysterious DataService.

About DataService

To be honest, I have scoured the entire Internet with the word "DataService," but obtained nearly nothing besides several discontinuous articles (such as this one on http://forums.asp.net) referring to it and the newest MS AJAX samples shipped with the framework. In addition, I use the object browser and the reflector tool inside Visual Studio 2005 to grab a little more info about it. So now I have pieced them together and drawn some conclusions on the mysterious "DataService."

Recently, from the web and MS AJAX tutorials, you can easily find many related tips on consuming general web services (derived from WebService) from inside the client-side JavaScript of ASP.NET AJAX framework, while there are few samples on DataService derived web services accessed from the client side. According to my preliminary research, DataService should be used under the following typical circumstance: when we use the advanced client-side rendering controls, such as ItemView, ListView, etc. and their data sources are database-related data operations (e.g. CRUD) provided by web services, while under the other kinds of circumstances we can choose the more common WebService. Is it true that Microsoft has specially designed DataService for ListView/ItemView? By examining the assemblyMicrosoft.Web.Preview.dll using the .NET object browser and Lutz Roeder's advanced .NET Reflector tool (note: this is an excellent thing; with it you can easily obtain the complete source code for class DataService). We have found DataService is derived from WebService and only exposed the following two Web Methods.

Listing 4

public DataTable <span class=Bold>GetData</span>(object parameters, string loadMethod);
public DataTable <span class=Bold>SaveData</span>(ChangeList changeList, object parameters, string loadMethod);

By examining the source code of Sys.Preview.Data.DataSource.save and Sys.Preview.Data.DataSource.load in file PreviewScript.js, you can easily find the following.

1. Method save requires that property serviceType of DataSource must be of type of Sys.Preview.Data.ServiceType.DataService and then the save method is directed to call method SaveData of class DataService.

2, There are two things with method load: when property serviceType of DataSource is of type of DataService, then the load method is directed to call method GetData of class DataService; when property serviceType of DataSource is not of type of DataService, i.e. Handler according to discuss with DataSource in Part 1, the system will create a general delegate and then method load is directed to Sys.Net.WebRequest(). When we further study the methods SaveData and GetData of class DataService using .NET Reflector, we can find more interesting thingsyou will know what the meaning of property loadMethod of DataSource is and how the database CRUD operations correspond to the Delete (DeleteRecords), Insert (InsertRecords), Select (SelectRecords), and Update (UpdateRecords) methods of your DataService and even more secrets…

For brevity, here we do not give their detailed analyses, but I leave this to the readers.

Author's Note: I highly recommend you study the source code of class DataService carefully, so that you can get the most of you originally want.

With the newly-introduced attributes, DataObjectMethod and DataObjectField (you can also refer to two classes DataObjectFieldAttribute and DataObjectMethodAttribute in MSDN for further research), we can easily achieve our aims in providing properties and methods to be used by control DataSource, such as Fill, Select, Update, Insert, and Delete operations. All these are to be provided by the easy xml-script declarative programming in the following section.

Implement the binding

Now, let us see how to use the xml-script declarative mode to achieve the ListView control data binding. Here is the xml-script part in correspondence with HTML elements definitions in Listing 2 above.

Listing 5

<script type="text/xml-script">
      <page xmlns="http://schemas.microsoft.com/xml-script/2005">
        <components>
       <dataSource id="EmployeeDataSource" serviceURL="EmployeeDataService.asmx" >
        </dataSource>
          
          <listView id="searchResults" itemTemplateParentElementId="searchResults_layoutTemplate" >
            <bindings>
              <binding dataContext="EmployeeDataSource" dataPath="data" property="data" />
            </bindings>
            <layoutTemplate>
              <template layoutElement="searchResults_layoutTemplate" />
            </layoutTemplate>
            <itemTemplate>
              <template layoutElement="searchResults_itemTemplate">
                <label id="searchResults_ID">
                  <bindings>
                    <binding dataPath="Id" transform="Add" property="text" />
                  </bindings>
                </label>
                <label id="searchResults_Name">
                  <bindings>
                    <binding dataPath="Name" property="text" />
                  </bindings>
                </label>
                <label id="searchResults_Address">
                  <bindings>
                    <binding dataPath="Address" property="text" />
                  </bindings>
                </label>
              </template>
            </itemTemplate>
            <separatorTemplate>
                 <template layoutElement="searchResults_separatorTemplate" />
            </separatorTemplate>
            <emptyTemplate>
                <template layoutElement="NoDataTemplate" />
            </emptyTemplate>
          </listView>
          
          <application>
            <load>
                <invokeMethodAction target="EmployeeDataSource" method="load" />
            </load>
        </application>  
        </components>
      </page>
</script>                    

In the first lines of code in bold, we have define a dataSource to be used in the following components. Note here that although not explicitly declared, the ServiceType property of this dataSource has been set to DataService. From the second part of code in bold, we start the concrete data binding, with property dataContext to specify the data source of ListView, dataPath to specify the binding property of the source, property to specify the bound property of the target. And further, we start to bind property Id of to property text of label searchResults_ID, property Name of to property text of label searchResults_Name, and property Address of to property text of label searchResults_Address. In the first binding, we introduce a transformer of type Add (there are several types, refer to the source code of class Sys.Preview.BindingBase in file PreviewScript.js). Since the value of property DataIndex exposed by DataTable (the data format bound to ListView when data from DataService arrives at the client side) starts from 0, using of Add transformer can automatically lead to its value plus 1, which will rather adapt to the flavors of common users. The final <application> block tells the system to automatically invoke the load method of data source EmployeeDataSource. Why load and what behind load? Please find the answer in the DataService discuss above.

Harvesting

It is no use wasting more words, so just see the final run-time screenshot in Figure 3.

Figure 3

When the sample application starts up, the data bindings automatically happen and then the ListView control gets rendered on the screen.

Sample 2 - database binding

Now, turns up the comparatively complex database binding sample. According to what we have discussed above, we find out the typical scenarios on using DataSource; and also, in Sample 1, we used an in-memory data source to simulate the web service calling with state. In practice, however, this is not recommended. In this section, we are to create a sample much closer to the enterprise development environment.

Introduction

1. Create the sample

Launch Visual Studio 2005 and then create a sample website named DatabaseBinding using the "ASP.NET AJAX CTP-Enabled Web Site" template, as well as choose Visual C# as the built-in language. Next, modify page Default.aspx as illustrated in Figure 4.

Figure 4: The design-time sample web page

2. Behind the scene

Here are the HTML elements definitions in page Default.aspx.

Listing 6

<!--------------------------------------------------->
        <div id="detailsView"></div>
        <!--------------------------------------------------->
        <input type="button" id="previousButton" value="Previous" title="Go to
 previous row" style="width: 67px; height: 30px;" />
        <span id="rowIndexLabel"></span>
        <input id="nextButton" type="button" value="Next" title="Go to next row"
 style="width: 67px; height: 30px;" />
        
        <input type="button"
 id="addButton" value="Add" title="Create a new row" style="width: 67px; height: 30px;" />
        <input type="button"
 id="delButton" value="Delete" title="Delete the current row" style="width: 67px; height: 30px;" />
        <input type="button"
 id="saveButton" value="Save" title="Save all pending changes" style="width: 67px; height: 30px;" />
        <input type="button"
 id="refreshButton" value="Refresh" title="Discard pending changes and get the latest data from the server"
 style="width: 73px; height: 30px" />
        <!--------------------------------------------------->
        <div style="visibility:hidden;display:none" >
            <div id="detailsTemplate" class="ListWindow">
                Name: <input id="nameField" size="30" /><br />
                Address:<br />
                <textarea id="addressField" style="width: 428px; height: 130px" rows="4"
 cols="4"></textarea><br />
            </div>
            <div id="emptyTemplate">
                Loading Data...
            </div>
        </div>

According to the layout in Figure 4 and the code above, we first define two navigator buttonspreviousButton and nextButton, which are used to navigate between the records of the client-side (NOT the server side!) data source of control ItemView. Next, we define two buttons (addButton, delButton) to modify the records in the database. The next two buttons, saveButton and refreshButton, are directly corresponding with the save and load methods of the MS AJAX client-side control DataSource. After that, a group of divs tags are used to describe MS AJAX control ItemView, with each div tag in response to each template of control ItemView. You can compare the layout and mappings for ItemView here with those for ListView in Sample 1.

Create a Web Service connected with the database

1. Create a sample databaseDataBind.mdf

By right click the project and select "Add new Item…" and then choose the template "SQL Database," you can easily create an empty databasehere we name it DataBind.mdf. Then, we add to it only one table named Employees with three fieldsId (int, primary key), Name (nvarchar(50), not empty), and Address (nvarchar(50), not empty). And also, we have created four simple stored procedures: DeleteRecord, GetAllRecords, InsertRecord, UpdateRecord, which are associated with the typical CRUD database operation. Here we will not talk more about this trivial since our interests do not lie in here.

2. Create a classEmployee

This class is very much like class Employees in Sample 1, which acts as the OOP packing with its attribute DataObjectField decorated member variables mapped to the fields defined in table Employees.

3. Two Helper classesSqlHelper (borrowed from Microsoft) and SqlTaskProvider

To make things easier and reusable, we have set up two helper classes: one is SqlHelper borrowed from Microsoft sampleTaskList, the other is SqlTaskProvider. Since these contents are far from our attention, we do not explain them either, and you can refer to the source code for details.

Now with the groundwork done, let us create a DataService (derived from Web Service) connected with the database.

2. Create a DataService to connect with database

Here is the key code snippet of file MyDataService.asmx.

Listing 7

//……(omitted)
using System.ComponentModel;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Data;
using System.Web.Script.Services;
using Microsoft.Web.Preview.Services;
using Demos.Employee; //defines class SqlTaskProvider
[WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo =
  WsiProfiles.BasicProfile1_1)][ScriptService]
public class MyDataService: DataService
{
  [WebMethod][DataObjectMethod(DataObjectMethodType.Delete)]
  public void DeleteRecord(Employee emp)
  {
    if (emp.Name == null)
    {
      throw new AccessViolationException();
    }
    new SqlTaskProvider().DeleteRecord(emp);
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Select)]
  public List < Employee > GetAllRecords()
  {
    return new SqlTaskProvider().GetAllRecords();
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Insert)]
  public void InsertRecord(Employee emp)
  {
    if (emp.Name == null)
    {
      throw new AccessViolationException();
    }
    new SqlTaskProvider().InsertRecord(emp);
  }
  [WebMethod][DataObjectMethod(DataObjectMethodType.Update)]
  public void UpdateRecord(Employee emp)
  {
    if (emp.Name == null)
    {
      throw new AccessViolationException();
    }
    new SqlTaskProvider().UpdateRecord(emp);
  }
}

With a little study, you can make clear the calling relations as shown in Figure 5.

Figure 5

Next, let us see how the data bindings are accomplished on the client side. Note here we still use the xml-script mode instead of the manual JavaScript programming.

Declarative programming on the client side

As with Sample 1, we first set up the mapping relationships between the HTML elements defined above and the templates of control ItemView.

Listing 8

<components>
                <dataSource id="EmployeeDataSource" serviceURL="MyDataService.asmx" >
                </dataSource>
                
                <itemView id="detailsView">
                    <bindings>
                      <binding dataContext="EmployeeDataSource" dataPath="data" property="data" />
                        <binding dataContext="EmployeeDataSource" dataPath="isReady"   
  <p class=Code-ASPXCxSpMiddle>property="element" propertyKey="enabled"/>
                    </bindings>
                    
                    <itemTemplate>
                        <template layoutElement="detailsTemplate">
                            <textBox id="nameField">
                                <bindings>
                                    <binding dataPath="Name" property="text" direction="InOut"/>
                                </bindings>
                            </textBox>
                            <textBox id="addressField">
                                <bindings>
                                    <binding dataPath="Address" property="text" direction="InOut"/>
                                </bindings>
                            </textBox>
                        </template>
                    </itemTemplate>
                    <emptyTemplate>
                        <template layoutElement="emptyTemplate" />
                    </emptyTemplate>
                </itemView>

Here, there are some points to be noticed. First, control ItemView is typically used for showing one record with MS AJAX client-side data binding solution, while control ListView is used for many records in some range. Second, control ItemView uses two bindings: the first binding will bind the data returned from DataSource to property data of control ItemView to ensure the ItemView can get its required integrated dataset from the data source; the second binding binds the property enabled of ItemView to the property IsReady of DataSource, which means that when the data source has not get ready, e.g. the data source is just reading/writing data from/to the server, the ItemView will be set disabled. Third, we have used two-way bindings, which means that not only will the changing of properties of the source control (the one pointed to by dataContext property) update the corresponding properties of the target control, but also the changing of the target control will affect the source control. So, in this example not only will the data changing in DataSource affect the data to be shown in the Textbox controls but contents of these Textbox controls affect the data of the DataSource. And also, we should notice that the changing of DataSource will make the data dirty - the property isDirty of the DataSource control will be set to true.

Next, come the definitions of the two navigator buttons.

Listing 9

                <button id="previousButton">
                    <click>
                        <invokeMethodAction target="detailsView" method="movePrevious" />
                    </click>
                    <bindings>
                          <binding dataContext="detailsView" dataPath="canMovePrevious" 
 property="element" propertyKey="disabled"
 transform="Invert" />
                    </bindings>                        
                </button>
                <label id="rowIndexLabel">
                    <bindings>
                        <binding dataContext="detailsView" dataPath="dataIndex"
 property="text" transform="Add" />
                    </bindings>
                </label>
                <button id="nextButton">
                    <click>
                        <invokeMethodAction target="detailsView" method="moveNext" />
                    </click>
                    <bindings>
                          <binding dataContext="detailsView" dataPath="canMoveNext" 
 property="element" propertyKey="disabled"
 transform="Invert" />
                    </bindings>                        
                </button>

Here, control ItemView supplies some methods and properties to be used to navigate between the records loaded into it. If the user is browsing the first record, then property canMovePrevious is set to false; or else true. In this example, when the user is browsing the first record, button previousButton is set disabled automatically. In addition, we specify a corresponding action for the click event of button previousButton: call method movePrevious of control ItemView. As for button nextButton, things are just the same. Moreover, we read the index value of current record in the dataset through property dataIndex, and bind it to a label control.

Now comes the most interesting and important part with database CRUD operations.

Listing 10

                <button id="addButton">
                    <click>
                        <invokeMethodAction target="detailsView" method="addItem" />
                    </click>
                    <bindings>
                          <binding dataContext="EmployeeDataSource" dataPath="isReady" 
 property="element" propertyKey="disabled" transform="Invert" />
                    </bindings>                        
                </button>
                
                <button id="delButton">
                    <click>
                        <invokeMethodAction target="detailsView" method="deleteCurrentItem" />
                    </click>
                    <bindings>
                          <binding dataContext="EmployeeDataSource" dataPath="isReady" 
 property="element" propertyKey="disabled"
 transform="Invert" />
                    </bindings>                        
                </button>
                
                <button id="saveButton">
                    <click>
                        <invokeMethodAction target="EmployeeDataSource" method="save" />
                    </click>
                    <bindings>
                          <binding dataContext="EmployeeDataSource"
 dataPath="isDirtyAndReady"  property="element"
 propertyKey="disabled" transform="Invert" />
                    </bindings>                        
                </button>
                
                <button id="refreshButton">
                    <click>
                        <invokeMethodAction target="EmployeeDataSource" method="load" />
                    </click>
                    <bindings>
                          <binding dataContext="EmployeeDataSource" dataPath="isReady" 
 property="element" propertyKey="disabled"
 transform="Invert" />
                    </bindings>                        
                </button>

When you need to add a new record to the dataset, you should call method addItem of control ItemView - only when the data source get ready can you call this method. As for button delButton, things are very similar. When the data source is ready, method deleteCurrentItem of control ItemView can be called; or else, button delButton is set disabled with data binding.

As for button saveButton, things become a bit complicated. Only when the dataset becomes dirty and the data source gets ready, can we save the data. You should recall that the TextBox controls defined inside the ItemTemplate of ItemView are all bond with two directions. So, when the user alters contents of any of the TextBox controls the dataset in control ItemView will be updated automatically, as well as the dataset in its data source. As a result, the data source becomes dirty, and at the same time, the data source gets ready, so property isDirtyAndReady will be set to true. And so, when the data source becomes dirty and gets ready, button saveButton is enabled or else disabled.

When you click button refreshButton there will occur a SELECT query, which will in turn trigger all the bindings and load the newest data into the controls on the web page. Note that the refresh operation occurs in the AJAX way (asynchronously), so only control ItemView is updated without traditional flickering on the whole web page.

4. Running the sample

Without any trouble, press F5 and you will see the runtime screenshot like Figure 6.

Figure 6:

In this screen you can operate with the records (possibly from a faraway database with the DataService as the intermedia) as those done in a traditional application. Is it easy?

Downloads

Conclusion

In the two articles of this series, we have examined the data binding architecture in Microsoft ASP.NET AJAX 1.0. Because I am also a newbie with this framework and this tool itself (especially the Futures CTP part) is still in progress, there must exist some errors in the concepts and the samples, please do not hesitate to help me out in any possible way. Finally, I wish you a happy journey with Microsoft ASP.NET AJAX framework!



User Comments

Title: binding the listview   
Name: silo
Date: 2010-08-02 8:14:52 AM
Comment:
the sample code has a crc error when i try to extract it.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 9:11:51 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search