To read the article online, visit http://www.4GuysFromRolla.com/articles/081308-1.aspx

Creating a Databound Label Control

By Scott Mitchell


Introduction


ASP.NET includes a number of data source and data Web controls that make it remarkably easy to work with data from a web page. For example, to display the results of a database query simply add and configure a SqlDataSource control and then bind that to a GridView, ListView, or some other data Web control. There's no need to write any source code; the data source controls allow declarative access to data. For more information on working with data in ASP.NET see my Accessing and Updating Data in ASP.NET article series and Working with Data tutorials.

The GridView and ListView controls are great for displaying a set of records, while the DetailsView and FormView controls are ideal for displaying information about a single record. There are times where we only need to display a single column from a single record. While you can certainly use the DetailsView or FormView controls for this, it would be easier to use a Label Web control. However, the Label control does not natively support data binding. As a result, to display a database needed in a Label Web control you need to write code (or put the Label in a FormView templates or a DetailsView TemplateField).

The good news is that the .NET Framework offers appropriate base classes that we can extend to build a databound Label Web control. This article shows how to create and use such a control. The control, which I named DataboundLabel, and its complete source code is available for download at the end of this article, along with a demo of the control in use. Read on to learn more!

Creating a Databound Web Control


ASP.NET already includes a bevy of databound Web controls. A databound Web control is one that can be declaratively bound to a data source Web control, such as a SqlDataSource control or an ObjectDataSource control. Additionally, a databound control can be bound programmatically by assigning the data to display to the control's DataSource property and then calling its DataBind method. Examples of databound controls include, among others, the:
  • GridView
  • ListView
  • DetailsView
  • CheckBoxList
  • DropDownList
All databound Web controls derived from the DataBoundControl class, which contains the essential methods and properties needed for data binding. To create a custom Web control that offers data binding functionality, create a new class that extends the DataBoundControl class and, at a minimum, overrides its PerformDataBinding method. The PerformDataBinding method is called whenever data binding needs to occur and is passed the data to be bound to the control. Your job then is to take that data and process it as needed so that it is displayed in your control's rendered output.

While this may sound a tad confusing, it is not too difficult to implement. The base class, DataBoundControl, handles the vast majority of work that needs to be performed. To illustrate how to build a databound control, I've created a Label Web control that supports data binding. I named this new control DataboundLabel; it's code is written in C# and is available for download at the end of this article. The remainder of this article examines the core code of this control and shows how to use it in an ASP.NET web page.

An Overview of How the DataboundLabel Control Works


The DataboundLabel control is meant to be used on a page when you want to display a single column from a single database record without having to write code or use a DetailsView or FormView control. To use this control, and to the page and then set its DataTextField property to the name of the database column whose value you want to display. You can also set the DataboundLabel control's DataTextFormatString property to specify a format string. For example, if you were displaying a column from a database record of type money you could use a DataTextFormatString value like "Cost: {0:c}", which would display "Cost: Value of the DataTextField column format as a currency value". (If these two properties don't make sense, don't worry as things will become clearer once we look at a demo.)

To specify the actual data that is bound to the DataboundLabel control you can use a data source Web control or programmatically bind the data. To use a data source would control, such as a SqlDataSource, you use the exact same steps as you would when binding a data source control to one of the built-in data Web contols (such as the GridView). In addition, you have all the same properties found in the Label Web control and can adjust the rendered appearance through variety of formatting properties (ForeColor, BackColor, Font, etc.). That's all there is to it.

Before we examine controls source code, let's take a moment to see the DataboundLabel control in action. The download available at the end of this article includes a demo page named DataboundLabelDemo.aspx that includes three DataboundLabel controls on the page. The first one, CategoryDesc, uses an AccessDataSource control to declaratively display the value of the Description field from the Categories database table for a particular category. The AccessDataSource uses the following SELECT statement:

SELECT [CategoryID], [CategoryName], [Description]
FROM [Categories]
WHERE ([CategoryID] = ?)

The DataboundLabel control displays the value of the Description field by setting its DataTextField property to the value "Description" and its DataSourceID property to the ID of the AccessDataSource control (SelectedCategoryDescDataSource). The DataboundLabel's DataTextFormatString property is set to "Description: {0}", which displays the text "Description:" immediately before the value of the Description field for the first record returned by the AccessDataSource control.

The DataboundLabel control's declarative markup follows:

<cc1:DataboundLabel id="CategoryDesc" runat="server"
                    DataSourceID="SelectedCategoryDescDataSource"
                    DataTextField="Description"
                    DataTextFormatString="Description: {0}">
</cc1:DataboundLabel>

As the following screenshot shows, the selected categories description is displayed. In this example, the page contains no code and four Web controls: a DropDownList for the categories, an AccessDataSource that returns all records from the Categories table, the DataboundLabel control, and another AccessDataSource control (SelectedCategoryDescDataSource) that returns information about the selected category.

The DataboundLabel control displays the selected category's description.

While this example uses the AccessDataSource control the DataboundLabel works equally well with the other data source controls (the SqlDataSource and ObjectDataSource), and can also have its data bound programmatically.

Creating the DataboundLabel Control


The DataboundLabel control is implemented as a class that extends DataBoundControl. The DataBoundControl class derives from the WebControl class, so it has all of the core Web control properties (ID, ClientID, ForeColor, Font, etc.). The DataboundLabel adds a handful of additional properties:
  • DataTextField - the name of the database column whose value is to be displayed.
  • DataTextFormatString - the format string applied to the value found in the DataTextField column (optional).
  • AssociatedControlID - Label Web controls can have an optional associated control. If a Label Web control has an associated control then when the label is clicked the associated control is activated. This is commonly used to associate a Label with a corresponding checkbox or other user input field.
  • TagKey - this is a protected property, so it is not accessible to the page developer. This property indicates the HTML element to use when rendering the control. If the AssociatedControlID property is set a <label> element is used, otherwise a <span> element is used. This behavior mimics the Label Web control's behavior.
  • Text - the actual text value displayed in the DataboundLabel. This property is read-only, as its value is determined when the data is bound.
An important thing to remember when working with properties for a data bound control is that for those properties whose value affects the data binding output you need to instruct the control to rebind to its data source when those values change. This entails calling the base class's OnDataPropertyChanged method in the set accessor of such properties. For the DataboundLabel control the OnDataPropertyChanged method needs to be called whenever values are assigned to the DataTextField or DataTextFormatString properties. Here's the code from the DataTextField property:

public virtual string DataTextField
{
   get
   {
      object o = this.ViewState["DataTextField"];
      if (o != null)
         return (string)o;
      else
         return string.Empty;
   }
   set
   {
      this.ViewState["DataTextField"] = value;

      base.OnDataPropertyChanged();


   }
}

The DataboundLabel control also contains a number of overridden methods. One of the most pertinent ones is RenderContents, which specifies the markup that is to appear between the <span> (or <label>) tags. This limitation is painfully simple - all we do is admit the value of the Text property:

protected override void RenderContents(HtmlTextWriter writer)
{
   writer.Write(this.Text);
}

Another key method is the override of PerformDataBinding. The PerformDataBinding method is called whenever data binding occurs and is passed to the data that has been bound to the control. Keep in mind that the data is usually a collection of records, but we are only interested in the first record. The code, shown below, gets the first record and uses the DataBinder.GetPropertyValue method to extract the value of the DataTextField from the record.

protected override void PerformDataBinding(System.Collections.IEnumerable data)
{
   base.PerformDataBinding(data);

   if (data != null)
   {
      // Clear out the Text property
      this.ClearText();

      string formatString = "{0}";
      if (string.IsNullOrEmpty(this.DataTextFormatString) == false)
         formatString = this.DataTextFormatString;

      // Get the DataTextFormatString field value for the FIRST record
      foreach (object obj in data)
      {
         if (base.DesignMode)
            SetText(string.Format(formatString, "abc"));
         else
         {
            if (string.IsNullOrEmpty(this.DataTextField))
               SetText(string.Format(formatString, obj.ToString()));
            else
               SetText(DataBinder.GetPropertyValue(obj, this.DataTextField, formatString));
         }

         break;
      }
   }
}

Note the use of the DesignMode property in the code above. The DesignMode property returns a Boolean value that indicates whether the control is being viewed from a web page or from Visual Studio designer. The call to the DataBinder.GetPropertyValue method is bypassed if the request comes from the Visual Studio Designer.

The ClearText and SetText methods clearer and write values to the Text property, respectively. These separate methods are needed because the Text property is read-only.

Using the DataboundLabel Control in an ASP.NET Web Page


The download available at the end of this article includes the complete source code for the DataboundLabel control, which is part of my skmControls2 control library. To use the skmControls2 controls in an ASP.NET website, copy the DLL to the website's /Bin directory and then add the following @Register directive to the tops of the .aspx pages where you want to use the controls:

<%@ Register Assembly="skmControls2" Namespace="skmControls2" TagPrefix="skm" %>

(Alternatively, you can add this @Register directive in the Web.config file so that you do not need to add it to every ASP.NET page that uses the controls. See Tip/Trick: How to Register User Controls and Custom Controls in Web.config.)

The download also includes a demo application that shows using the DataboundLabel control declaratively with an AccessDataSource control and an ObjectDataSource control. There is also an example of programmatically binding the data to the DataboundLabel control.

Happy Programming!

  • By Scott Mitchell


    Attachments


  • Download the code used in this article

    Further Reading


  • Working with Data (includes VB & C# versions!)
  • Accessing and Updating Data in ASP.NET
  • Developing Custom Data-Bound Web Server Controls for ASP.NET 2.0
  • Walkthrough: Creating a Custom Data-Bound ASP.NET Web Control for ASP.NET 2.0
  • Article Information
    Article Title: ASP.NET.Creating a Databound Label Control
    Article Author: Scott Mitchell
    Published Date: August 13, 2008
    Article URL: http://www.4GuysFromRolla.com/articles/081308-1.aspx


    Copyright 2014 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers