• home
  • forum
  • my
  • kt
  • download
  • Databinding

    Author: 2007-07-04 15:24:31 From:

    After completing this tutorial, you will be able to

    • Represent collections using databound controls

    • Talk to database providers in ASP.NET

    • Customize databound controls

    This tutorial covers one of ASP.NET's most useful features: databinding. A number of controls within ASP.NET have the capability to understand the form and content of a collection and to render the correct tags to represent such user elements as list boxes, radio button lists, and combo boxes. Here we'll examine how these controls work and how to use them on a Web page.

    One of the most common problems encountered in building any software (and Web sites in particular) is representing collections as user interface elements. Think about some of the sites you have recently visited. If you ordered something from a commercial site, you no doubt hit a page that asked you to enter your address. What happened when you reached the State field? Most Web sites display a drop-down list box from which you may choose a state abbreviation.

    How was that drop-down list filled? In HTML, the <selection> tag nests several <option> tags that represent the elements to be listed. The state abbreviations probably came from a database or some other well-established source. Somewhere (most likely at the server), some piece of code had to go through the collection of states and render <selection> and <output> tags for it.

    ASP.NET server-side controls, such as the ListBox and the DropDownList, include Items collections. For example, one way to render a collection as a combo box is to declare a combo box on your ASP.NET page and add the items individually via the Items.Add method like so:

    protected void BuildComboBox(IList techList)
    {
       for(int i = 0; i < techList.Count; i++)
       {
             this.DropDownList2.Items.Add(techList[i]);
       }
    }

    Because representing collections as UI elements is such a prevalent programming task, it makes a lot of sense to push that down into the framework if at all possible. ASP.NET includes a number of databound controls that are capable of taking collections and rendering the correct tags for you. Let's see how this works.

    Each of the databound controls within ASP.NET includes properties to attach it to a data source. For simple databinding, these controls include a DataSource property to which you may attach any collection that implements the IEnumerable interface (as well as the DataSet and DataTable classes that we'll see shortly). After attaching the collection to the control, you call DataBind on the page (or the control) to instruct the control to iterate through the collection.

    For more complex databinding, some controls include a property named DataSourceID. This new style of databinding is named declarative databinding. Instead of simply iterating through a collection, the declarative databinding classes use a separate Data control to manage data for the databound control. These data managers support the databound controls in implementing standard functionality such as sorting, paging, and editing. Declarative binding greatly simplifies the process of rendering collections. They work by referencing the ID of a DataSource control on the page. .NET includes several of these DataSource controls¡ªincluding one for XML data, one for Access databases, and one for SQL Server, among others. With declarative databinding, calling DataBind is optional. The control will call DataBind during the Pre[[<img src="images/shy.gif"/>]]Rendering event.

    ASP.NET includes a number of controls that support at least simple databinding, while others support declarative databinding as well. These controls include those based upon the ListControl, the CheckBoxList, the RadioButtonList, the DropDownList, and the ListBox. In addition, the more advanced controls include the TreeView, the Menu, the GridView, the DataGrid, the Repeater, the FormView, and the DetailsView.

    Here's a rundown of how each control works.

    ListControl-Based Controls

    The most common databound controls are those based upon the ListControl base class. These controls include the ListBox, the BulletedList, the RadioButtonList, the CheckBoxList, and the DropDownList. We'll see these controls in detail in a moment. The names are self-explanatory for the most part. They all have direct analogs in Windows desktop programming as well as standard HTML control tags. The ListBox displays a list of strings. The DropDownList is similar to a ComboBox. The RadioButtonList displays a group of mutually exclusive radio buttons. The CheckBoxList displays a column of check box controls.

    TreeView

    We saw an example of the TreeView in Tutorial 6. The TreeView control represents hierarchical data. It's perfect for matching up with XML data sources. The TreeView features collapsible nodes that allow users to drill down from abstract data elements into more detailed ones. The TreeView supports declarative databinding.

    Menu

    The Menu control also handles hierarchical databinding. The Menu control gives users the ability to navigate the site in much the same way that menus for desktop applications do. The Menu supports declarative databinding.

    FormView

    The FormView control supports free-form layout for individual controls (such as a TextBox or a ListBox) that render data from a data source. The FormView also supports editing of data in the data source through the controls. The FormView supports declarative databinding.

    GridView

    While ASP.NET 1.x supported only the DataGrid control, ASP.NET 2.0 supports a DataGrid on steroids¡ªthe GridView. The GridView control is what it says it is¡ªit renders collections via a grid with individual columns and rows. Each row in the grid represents an individual record in a collection. Each column within that row represents an individual field within the record. While the original DataGrid required you as a developer to manage paging and sorting of data, the GridView control supports automatic paging and sorting. The GridView also supports editing (something that requires hand-coding in the DataGrid). The GridView supports declarative databinding.

    DetailsView

    Whereas the GridView gives you the whole gestalt of a data source, the DetailsView control is for drilling down to display one record at a time. The DetailsView is often paired with controls such as the ListBox, the DropDownList, or the GridView. Users select the row using one of these controls and the DetailsView shows the associated data. The DetailsView supports declarative databinding.

    DataList

    Whereas the DataGrid and the GridView display the data in a data source using regular rows and columns, the DataList control displays the records in a data source in a format you determine using template controls.

    Repeater

    The Repeater control also displays data from a data source in a format you determine (rather than forcing it into rows and columns). The Repeater control uses both raw HTML and server-side controls to display the rows. The Repeater control repeats the format you define for each row.

    The simplest databinding entails attaching a simple collection to one of the ListControl-based control's DataSource property. If you have a collection, you can simply set the DataSource property of one of these controls and it will render the correct tags automatically.

    The following example shows how to use some of the databound controls by hooking up an ArrayList to several of the ListControl-based controls.

    Databinding with an ArrayList

    1. Start a new Web site named DataBindORama.

    2. From the Web site menu, select Add New Item¡­ and add a class named TechnologyDescriptor. Add two member variables to the class: String types named _strTechnologyName and _strDescription. This class will represent a technology name and an accompanying description. Expose these two member variables as public properties.

      IMPORTANT
      Exposing the member variables as properties is important so the controls will work correctly with databinding. When a control binds to a collection composed of classes, it will look for the fields to expose via their property names. Using the databinding controls, you may specify a ¡°display name¡± (that is, the value that will appear in the control), and you may specify a second ¡°hidden¡± value to be associated with the item that was selected. In the case of rendering collections of managed objects, the binding architecture depends upon these fields being exposed as properties.

      Listing 11-1 shows the TechnologyDescriptor that exposes a technology name and description as properties.

      Listing 11-1

      public class TechnologyDescriptor
      {
         protected String _strTechnologyName;
         protected String _strDescription;
       
       public String TechnologyName
         {
            get
            {
               return this._strTechnologyName;
            }
            set
            {
               this._strTechnologyName = value;
            }
       
       }
         public String Description
         {
            get
            {
               return this._strDescription;
            }
            set
            {
               this._strDescription = value;
            }
         }
       
       public TechnologyDescriptor(String strTechnologyName,
                     String strDescription)
         {
            this._strTechnologyName = strTechnologyName;
            this._strDescription = strDescription;
         }
      }
    3. After developing the TechnologyDescriptor class, add four databound controls to the default page: a ListBox, a DropDownList, a RadioButtonList, and a CheckBoxList.

    4. Underneath each of these controls, place a Label. The label will be used to show the value associated with each selected item.

    5. Set the AutoPostBack property for the ListBox, the DropDownList, the RadioButtonList, and the CheckBoxList to true. That way, selecting an item in each of the controls will cause a post back during which the selected item may be interrogated.

      Graphic
    6. Now update the page to build a list of TechnologyDescriptors and to attach the collection of TechnologyDescriptors for each control. For each control, set the DataTextField property to ¡°TechnologyName¡± (to map it to the TechnologyDescriptor's TechnologyName property). This will ensure that the technology name will appear in the control. Then set the DataValueField for each control to ¡°Description¡± to map the Description property to be the associated value. Listing 11-2 shows creating a collection of TechnologyDescriptors and attaching the collection to each of the controls.

    7. Add selection handlers for each of the controls (by double-clicking them). Upon receiving the selection events, interrogate the control for the selected item's value. Listing 11-2 also shows the handlers.

      Listing 11-2

      protected void Page_Load(object sender, EventArgs e)
      {
         Ilist techList = CreateTechnologyList();
         if (!this.IsPostBack)
         {
            this.ListBox1.DataSource = techList;
            this.ListBox1.DataTextField = "TechnologyName";
       
            this.DropDownList1.DataSource = techList;
            this.DropDownList1.DataTextField = "TechnologyName";
       
            this.RadioButtonList1.DataSource = techList;
            this.RadioButtonList1.DataTextField = "TechnologyName";
       
            this.CheckBoxList1.DataSource = techList;
            this.CheckBoxList1.DataTextField = "TechnologyName";
       
            this.DataBind();
         }
      }
      protected Ilist CreateTechnologyList()
      {
         ArrayList alTechnologies = new ArrayList();
      
         TechnologyDescriptor technologyDescriptor;
      
         technologyDescriptor =
         new TechnologyDescriptor("ASP.NET", "Handle HTTP Requests");
         alTechnologies.Add(technologyDescriptor);
      
         technologyDescriptor =
         new TechnologyDescriptor("Windows Forms",
         "Local Client UI technology");
         alTechnologies.Add(technologyDescriptor);
      
         technologyDescriptor =
         new TechnologyDescriptor("ADO.NET",
         "Talk to the database");
         alTechnologies.Add(technologyDescriptor);
      
         technologyDescriptor =
         new TechnologyDescriptor(".NET CLR",
         "Modern runtime environment for managed code");
         alTechnologies.Add(technologyDescriptor);
      
         technologyDescriptor =
         new TechnologyDescriptor(".NET IL",
         "Intermediary representation for .NET applications");
         alTechnologies.Add(technologyDescriptor);
      
         technologyDescriptor =
         new TechnologyDescriptor(".NET Compact Framework",
         "Modern runtime environment for small devices");
         alTechnologies.Add(technologyDescriptor);
      
         return alTechnologies;
      }
      
      protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
      {
         this.LabelListBoxSelectedValue.Text = this.ListBox1.SelectedValue;
         }
      protected void DropDownList1_SelectedIndexChanged(object sender,
         EventArgs e)
      {
         this.LabelDropDownListSelectedValue.Text =
         this.DropDownList1.SelectedValue;
      }
      protected void RadioButtonList1_SelectedIndexChanged(object sender,
          EventArgs e)
      {
         this.LabelRadioButtonListSelectedValue.Text =
         this.RadioButtonList1.SelectedValue;
      }
      protected void CheckBoxList1_SelectedIndexChanged(object sender,
         EventArgs e)
      {
         this.LabelCheckboxListSelectedValue.Text =
         this.CheckBoxList1.SelectedValue;
      }
    8. Compile the site and browse to the page.

      Graphic

    In the above example, selecting one of the items within the databound controls will reveal the related value in the label beneath the control.

    In certain programming situations, you may find yourself doing this kind of databinding. For example, simple collections such as states within the United States or short lists (perhaps of employee or contact names) work great with these ListControl-based controls. However, very often you'll find yourself dealing with data in a more complex format¡ªbeyond simply an ArrayList. A number of controls can deal with more complex DataSets. However, we first need to look at ADO.NET because it provides the easiest way to reach these more complex data compositions.

    The previous example shows how to attach in-memory collections (such as ArrayLists) to a server-side control and have it render the correct tags to the client. While this is useful, the server-side controls are capable of working with other collections¡ªincluding ones that come from databases. Before seeing how to render database queries using UI elements, let's take a quick look at the .NET database story.

    Just as .NET includes a library of classes for managing rich client UI (Windows Forms) and for handling HTTP requests (ASP.NET), .NET includes a library for connecting to a wide range of databases. That library is named ADO.NET.

    ADO.NET is similar to Microsoft's previous database technology (named simply ADO). ADO stands for Active Data Objects. While Microsoft has dropped ¡°Active¡± from its marketing lexicon, it kept the name ADO and appended ¡°.NET¡± to name the managed database technology (surely for brand name recognition). ADO represents a set of managed providers that is very similar in function and form to classic ADO. ADO.NET centers around three main units of functionality: connecting to a database, commanding the database, and using the results.

    Connections

    When you want to talk to a specific database, you usually need to connect to it. At the very least, most of the time this involves specifying the location of the database. For many scenarios, connecting also requires managing security (via user names and passwords). More advanced scenarios may also require dealing with such issues as connection pooling and transactions. These are all handled as part of the process of connecting to the database. The connection information is usually passed in via a string, which sets various connection parameters.

    ADO.NET has classes for making connections to a database. ADO.NET 1.x included only two: a connection for Microsoft SQL Server and another for connecting to OLEDB databases. ADO.NET 2.0 adds classes specialized for more database types and includes a new set of database services using the provider pattern.

    Working with ADO.NET 1.x involved writing most of the data access code using the ADO interfaces (rather than directly instantiating the database classes). This allowed you to isolate the vendor-specific details in a single place in the code¡ªin the spot where the connection is managed. After that, getting the other parts required for making queries (for example, getting the correct command object) was a matter of asking the connection for it. While you may still write code to connect to the database using ADO.NET 1.x¨Cstyle code, there's now a better way¡ªusing the ADO.NET 2.0 database provider factories.

    As mentioned previously, ADO.NET 2.0 offers the provider pattern, an improvement in connecting to and using databases. By using the provider pattern, you limit exposing the kind of database you're using to a single call to a provider factory. You choose the kind of database in one place and the provider takes care of making sure the correct connection and command objects are used. This was less important in ADO 1.x when ADO divided the database world into two kinds of databases: SQL Server and OLEDB databases. However, with its support of new database types, the provider pattern is a welcome addition.

    If you look in Machine.Config, you'll see providers for the following database types:

    • Odbc Data Provider

    • OleDb Data Provider

    • OracleClient Data Provider

    • SqlClient Data Provider

    • SQL Server CE Data Provider

    Listing 11-3 shows a snippet from Machine.Config illustrating how the provider keys are mapped to provider factories.

    Listing 11-3

    <system.d<configuration>
     <system.data>
        <DbProviderFactories>
          <add name="Odbc Data Provider"
               invariant="System.Data.Odbc"
               type="System.Data.Odbc.OdbcFactory¡­" />
          <add name="OleDb Data Provider"
               invariant="System.Data.OleDb"
               type="System.Data.OleDb.OleDbFactory¡­"/>
          <add name="OracleClient Data Provider"
               invariant="System.Data.OracleClient"
               type="System.Data.OracleClient.OracleClientFactory¡­"/>
          <add name="SqlClient Data Provider"
               invariant="System.Data.SqlClient"
               "System.Data.SqlClient.SqlClientFactory" />
          <add name="SQL Server CE Data Provider"
               invariant="Microsoft.SqlServerCe.Client"
               type="Microsoft.SqlServerCe.Client.SqlCeClientFactory¡­" />
        </DbProviderFactories>
      </system.data>
    </configuration>>

    To get a connection to a database, you ask the runtime for a reference to the right factory and then get a connection from the factory, as shown in Listing 11-4. You use the name of the database type (System.Data.SqlClient or Microsoft.SqlServerCe.Client, for example). After getting the right kind of factory, you ask it to create a connection for you.

    Listing 11-4

    DbConnection GetConnectionUsingFactory()
    {
      DbProviderFactory dbProviderFactory =
            DbProviderFactories.GetFactory("System.Data.SqlClient")
      return dbProviderFactory.CreateConnection();
    }

    Once you have a connection, you may use it to connect to the database. Given a SQL Server database named AspDotNetStepByStep available on your machine, you'd insert a connection string as shown in Listing 11-5 in your Web.Config. You could type it in manually¡ªor, as we saw in Tutorial 9, you may use the ASP.NET configuration utilities to add the connection string to the application's configuration. Listing 11-5 shows how this might appear in a Web.Config file.

    Listing 11-5

    <configuration>
     <connectionStrings>
    <add name="AspDotNetStepByStep"
         connectionString=
              "server=.;integrated security=sspi;database= AspDotNetStepByStepDB "/>
    </connectionStrings>
    </configuration>

    Once you have a reference to the database connection, you may open the connection and start commanding the database.

    Commands

    Once connected, the database is waiting for you to send database commands. These commands usually include querying the database, updating existing data, inserting new data, and deleting data. Most databases support Structured Query Language (SQL) to manage these commands. (Some databases may support specialized variations of SQL, so the actual command text may differ from one implementation to the other.) Commanding the database usually entails writing SQL statements such as

    Select * from DotNetReferences where AuthorLastName = Petzold

    For example, to connect to an SQL database named AspDotNetStepByStepDB and query the DotNetReferences table for all the references by someone with the last name ¡°Petzold,¡± you'd use code as shown in Listing 11-6.

    Listing 11-6

    class UseDBApp {
     static void Main(string[] args) {
      DbProviderFactory dbProviderFactory =
            DbProviderFactories.GetFactory("System.Data.SqlClient")
      DbConnection conn = dbProviderFactory.CreateConnection()
      using(conn) {
       ConfigurationSettings s =
        ConfigurationSettings.ConnectionStrings["AspDotNetStepByStep"];
       conn.ConnectionString = s.ConnectionString;
       conn.Open();
     
       DbCommand cmd = conn.CreateCommand();
       cmd.CommandText =
         "SELECT * FROM DotNetReferences WHERE AuthorLastName=Petzold";
       DbDataReader reader = cmd.ExecuteReader();
       // do something with the reader
      }
    }

    Executing the command using ExecuteReader sends a query to the database. The results come back via an instance of the IDataReader interface. The code listed above stops short of using the results. Let's take a look at how that works.

    Managing Results

    Once you've connected to the database and issued a query, you probably need to sift through the data to use it. ADO.NET supports two broad approaches to managing result sets: the IDataReader interface and the DataSet class.

    DataReader

    The example above retrieves an IDataReader from the query operation. The IDataReader interface is useful for iterating through the results of the query. Listing 11-7 shows part of the IDataReader interface.

    Listing 11-7

    public interface IDataReader
    {
       bool IsClosed {get;}
       int    RecordsAffected {get;}
       void Close();
       bool NextResult();
       bool Read();
    //..¡­
    }

    When iterating through the results of a query, Read fetches the next row. NextResult will fetch the next result set.

    Accessing data through IDataReader is often termed ¡°fire hose mode¡± because you have to eat your way through the data one row at a time going forward only. There's no way to revert back to a previous row except by resetting the reader and starting again. An alternative to accessing data through the IDataReader interface is to use a DataSet.

    DataSet

    In addition to the IDataReader, ADO.NET supports the notion of a disconnected record set¡ªthe DataSet class in ADO.NET. The ADO.NET is primarily designed to help you write large, highly scalable applications. One of the biggest hindrances to scalability is the limits of database connectivity. Databases usually have a limit on the number of active connections available at one time, and if all the connections are in use at any particular time, any piece of code wanting a database connection will need to wait. If the number of users of a system is about the same as the number of connections available, then perhaps that's not a problem. However, if the number of users of a system is greater than the number of database connections, the system performance will likely be impacted greatly.

    To encourage scalability, ADO.NET includes a class named DataSet that's designed to give you an easily navigable snapshot of your application's database. The idea behind a database is to get in and get out quickly with a copy of the data.

    Objects in the DataSet class are usually built using a DataAdapter. A DataSet includes a Data[[<img src="images/shy.gif"/>]]Table array¡ªone for each selection statement in the query. Once the DataAdapter comes back from fetching the DataSet, you have the latest snapshot of the database in memory. The DataSet contains a DataTable collection and creates a DataTable element for each SELECT statement in the query. You may access the Tables collection using either ordinal or String-type indices. Once you get to a table, iterating through the rows and columns is a matter of indexing into the table using ordinal indices for the rows and ordinal or String-type indices for the columns. Listing 11-8 shows an example of using the SqlDataAdapter to get a DataSet.

    Listing 11-8

    public static void UseDataSet()
    {
       DataSet ds = new DataSet();
       try
       {
          SqlDataAdapter da = new SqlDataAdapter(
             "select * from customer; select * from country",
             "server=.;uid=sa;pwd=;database=ASPNetStepByStepDB");
          da.Fill(ds, "DotNetReferences");
       }
       catch(SqlException e)
       {
          System.Console.WriteLine(e);
       }
     
     foreach (DataTable t in ds.Tables)
       {
          Console.WriteLine("Table " + t.TableName + " is in dataset"");
          Console.WriteLine("Row 0, column 1: " + t.Rows[0][1]);
          Console.WriteLine("Row 1, column 1: " + t.Rows[1][1]);
          Console.WriteLine("Row 2, column 1: " + t.Rows[2][1]);
       }
       ds.WriteXml("c:\\dataset.xml");
       ds.WriteXmlSchema("c:\\dataset.xsd");
    // also¡ª may bind to the tables here:
    this.ListBox1.DataSource = ds.Tables[0];
    this.ListBox1.TextDataField = "AuthorLastName"
    this.ListBox1.DataBind();
    }

    The code in Listing 11-8 illustrates using a DataAdapter and a DataSet. The code prints out the first two columns of the first three rows of each table in the DataSet. The example in Listing 11-8 shows that a DataTable is valid as a DataSource for databound controls. The example also shows that the DataSet objects also serialize as XML. Both the table schema and the contents may be serialized this way¡ªmaking it especially useful for transferring data between systems.

    Here's one final note about items in the DataSet class. They're disconnected and are not restricted to the ¡°fire hose mode¡± of data access. You have complete random access to any table, any column, and/or any row in the DataSet. In fact, objects in the DataSet class are also smart enough to keep track of any data you change inside of them. You may flush the data back to the physical database by using the CommandBuilder to prepare the DataSet for an Update through the DataAdapter.

    Given either an IDataReader or a DataSet, the databound controls will automatically render themselves appropriately to show the control on the browser. While you may always connect to the database and fetch the data manually through the standard connection/command architecture, ASP.NET 2.0 and Visual Studio 2005 support an even easier-to-use way to render data¡ªvia declarative databinding.

    After seeing how to access data in the raw using ADO.NET, let's look at an easier way. ASP.NET 2.0 includes some new classes that hide the complexity of managing connections and of gathering data. They're the DataSource controls.

    These DataSource controls abstract the entire connection and command mechanism so that all you need to do is decide on a data source, point the control there, and invent a query. Visual Studio provides a wizard that guides you through this. Once you have a DataSource, you may attach it to a databound control that uses it.

    Let's take a look at making a query and populating some controls with the results of the query.

    Use a DataSource to Populate Controls in DataReader Mode

    1. Add a new form to DataBindingORama named DataBindingWithDB.

    2. Set up an accessor for the database. Go to the Data controls in the toolbox. Drag an AccessDataSource onto the form. Select Configure Data Source¡­ from the local menu displayed by Visual Studio. Click Browse in the Configure Data Source dialog box. You'll see a directory named App_Data in the list box on the left side. Highlight it. Then select ASPStepByStep.mdb from the list box on the right side. This will insert an Access database accessor into your project. Configure the data accessor to use the AspDotNetStepByStep database that comes with this tutorial.

      Graphic
    3. Select all the columns and all the rows from the DotNetReferences table when configuring the query (that is, choose ¡°*¡± to query for all the columns).

      Graphic
    4. Test the query if you want to by clicking the Test Query button.

      Graphic
    5. Set the DataSourceMode property to DataReader.

    6. Now drag a ListBox onto the page. Set the AutoPostback property to true. Handle the Page_Load method by attaching the ListBox DataSource to the AccessDataSource1 like so:

          protected void Page_Load(object sender, EventArgs e)
          {
            if (!this.IsPostBack)
            {
               this.ListBox1.DataSource = this.AccessDataSource1;
               this.ListBox1.DataTextField = "AuthorLastName";
               this.ListBox1.DataValueField = "Title";
               this.ListBox1.DataBind();
            }
          }
    7. Put a label near the bottom of the page. This label will hold the selected value from the combo box.

    8. Double-click on ListBox1 to handle the item changed event. In the event handler, set the Label1 text property to the value field of the selected item.

         protected void RadioButtonList1_SelectedIndexChanged(object sender,
                EventArgs e)
         {
            this.Label1.Text = this.RadioButtonList1.SelectedItem.Value;
         }
    9. Now drag a RadioButtonList onto the form. When you finish dropping it on the form, Visual Studio will ask you if you want to choose a data source. Click Choose Data Source¡­.

      Graphic
    10. Configure the control to use AccessDataSource1 that you just added.

      Graphic
    11. Configure the control to use the AuthorLastName column for the text field and the Title column for the value field.

      Graphic
    12. Double-click on the RadioButtonList1 object on the form to create a handler for the radio button selection. Handle the selection by updating the Label1 object with the value associated with the current radio button selection.

         protected void RadioButtonList1_SelectedIndexChanged(object sender,
                EventArgs e)
         {
            this.Label1.Text = this.RadioButtonList1.SelectedItem.Value;
         }
    13. Now run the program. The ListBox and the RadioButton list should show the AuthorLastName field. Selecting one name out of either list will cause a post back and show the title (the associated value) in the label near the bottom of the page.

      Graphic

    Now we've had a taste of how binding to the simple controls works. While using these controls is common in many scenarios, the databound controls don't end there. ASP.NET includes other more complex controls that render data such as complex UI elements as grids and control constellations.

    In addition to the simple bound controls, ASP.NET includes several more complex controls. They work very much like the simple bound controls in that you attach a data source to them and they render automatically. However, these controls differ by displaying the data in more elaborate ways. These controls include the GridView, the FormView, the DetailsView, and the DataList.

    The best way to understand the nature of these controls is to work through a couple of examples. Let's start with the GridView.

    The GridView

    1. Add a new Web form to the DataBindORama site. Name it UseGridView.

    2. Pick up a GridView from the toolbox (it's under the Data controls). Drop it on the form. Visual Studio will ask you to configure the GridView. Under the Choose Data Source¡­ option, select <New data source¡­>. Point Visual Studio to the ASPNetStepByStep.mdb under the App_Data directory. When specifying the query, select ¡°*¡± to query for all the columns. Finally, enable Paging, Sorting, and Selection from the GridView Configuration menu. After configuring the GridView, Visual Studio will show you a representation of the format the query will use when it is rendered to the browser:

      Graphic
    3. Run the program. Try the various options such as paging through the data and sorting to get a feel as to how the GridView works.

      Graphic
    4. Go back to Visual Studio and try formatting the GridView to change its appearance. As with all the other ASP.NET controls, the GridView includes a number of configurable properties such as the foreground and background colors. Some of the other specialized properties within the GridView include the AlternateRowStyle, the PagerSettings, and the PagerStyle.

    The GridView is useful for displaying tables in a format where you can see all the rows and columns at once. While the classic DataGrid is still available, the GridView handles tasks such as selecting rows and sorting by column.

    Here's a look at another complex control: the FormView.

    The FormView

    1. Add a new Web form to the DataBindORama site named UseFormView.

    2. Pick up a FormView from the toolbox (it's under the Data controls). Drop it on the form. Visual Studio will ask you to configure the FormView. Under the Choose Data Source¡­ option, select <New data source¡­>. Point Visual Studio to the ASPNetStepByStep.mdb under the App_Data directory. When specifying the query, select ¡°*¡± to query for all the columns.

    3. Select the AutoFormat option from the Configuration menu. Here you have the opportunity to apply a couple of canned styles to the FormView. The example accompanying this text uses the classic style.

    4. Finally, enable paging from the FormView Configuration menu by selecting the Enable Paging check box. Set the HeadingText property to give the FormView a title (perhaps something like ¡°.NET Reference Authors and Titles¡±).

    5. After configuring the FormView, Visual Studio will show you a representation of the format the query will use when it is rendered to the browser:

      Graphic
    6. Run the program. Try the various options such as paging through the data to get a feel for how the FormView works.

      Graphic

    The FormView is useful for gathering the information for singular rows in one place. The user navigates between each row, but the focus is always on the current row.

    The DetailsView

    1. Add a new Web form to the DataBindORama site named UseDetailsView.

    2. Pick up a DetailView from the toolbox (it's under the Data controls). Drop it on the form. Visual Studio will ask you to configure the DetailsView. Under the Choose Data Source¡­ option, select <New data source¡­>. Point Visual Studio to the ASPNetStepByStep.mdb under the App_Data directory. When specifying the query, select ¡°*¡± to select all the columns.

    3. Select the AutoFormat option from the Configuration menu. Here you have the opportunity to apply a couple of canned styles to the DetailsView. The example accompanying this text uses the classic style.

    4. Select the Edit Fields¡­ option from the Configuration menu. Check the Auto-Generate fields check box on the dialog box.

    5. Finally, enable paging from the DetailsView Configuration menu. Set the HeadingText property to give the FormView a title (perhaps something like ¡°.NET Reference Authors and Titles¡±).

    6. After configuring the DetailsView, Visual Studio will show you a representation of the format the query will use when it is rendered to the browser:

      Graphic
    7. Run the program. Try the various options such as paging through the data to get a feel as to how the DetailsView works.

      Graphic

    The DataList control was available in ASP.NET 1.x. It's been updated to support declarative databinding. Here's a look at the DataList.

    The DataList

    1. Add a new Web form to the DataBindORama site named UseDataList.

    2. Pick up a DataList from the toolbox (it's under the Data controls). Drop it on the form. Visual Studio will ask you to configure the DataList. Under the Choose Data Source¡­ option, select <New data source¡­>. Point Visual Studio to the ASPNetStepByStep.mdb under the App_Data directory. When specifying the query, select ¡°*¡± to query for all the columns.

    3. Select the AutoFormat option from the Configuration menu. Here you have the opportunity to apply a couple of canned styles to the DataList. The example accompanying this text uses the slate style.

    4. Select the DataList Properties dialog box from the DataList Configuration menu by selecting Property Builder. Make sure the Show header and the Show footer check boxes are selected.

      Graphic
    5. Set the Caption property to give the DataList a title (perhaps something like: ¡°.NET Reference Authors and Titles¡±).

    6. After configuring the DataList, Visual Studio will show you a representation of the format the query will use when it is rendered to the browser:

      Graphic
    7. Run the program to see how the DataList renders itself.

      Graphic


    In this tutorial, we looked at ASP.NET's support for databound controls. While it's not rocket science to iterate through a collection and add the data to ASP.NET's server-side controls, it's a fairly common operation. That Microsoft pushed it down into the Framework classes is a good thing.

    One of the advantages of these controls is that they don't care at all where their data comes from. The data might be as simple as an ArrayList composed of .NET types (with each element in the array representing a row and each property representing a column). On the other hand, the data bound to a control might be as complex as IDataReader or a DataSet acquired from a physical database.

    Looking at databound controls invariably involves mentioning the ASP.NET database story: ADO.NET. The ADO.NET managed classes are for connecting to the database, commanding the database, and harvesting the results afterward. While connecting to the database manually (via .NET 1.x-style code) is still supported, .NET version 2.0 and Visual Studio 2005 offer an easier way to associated controls with data via the DataSource controls.

    ASP.NET includes a number of databound controls that may be matched up with a collection or (in the case of certain DataSource controls) a data source. The controls then assume the burden of iterating through the data and rendering the correct tags to the client.

    To

    Do This

    Bind a collection to a control

    Set the control's DataSource property to the collection

    Choose a column to display in the control

    Set the control's TextTextField property to the column name

    Choose a column to use programmatically (that's NOT displayed in the control)

    Set the control's TextValueField property to the column name

    Display a DataTable as a grid

    Use the DataGrid or the GridView controls

    Display a DataTable as a formatted, repeating list

    Use either the DataList or the Repeater

    Make a class' member variables available as DataTextFields and DataValueFields within a control

    discuss this topic to forum

    relation tutorial

    No relevant information

    Category

      NET (110)

    New

    Hot