How to: Customize Data Field Appearance and Behavior in the Data Model

ASP.NET Dynamic Data includes field templates that render the UI for displaying and editing data fields. You can customize the UI by changing existing field templates and by creating new custom field templates.

This topic describes how to customize data field appearance and behavior by following these steps:

  • Applying the UIHintAttribute attribute to a data field in the data model. This instructs Dynamic Data to use specific custom field templates to process a data field.

  • Creating the corresponding custom field templates to render the UI for displaying and for editing a data field.

When you customize a data field in the data layer, as shown in this topic, the customization applies globally to a Web site. Dynamic Data uses the custom field templates instead of the built-in templates (which are selected based on the data field intrinsic type) to display and modify the data field.

Alternatively, you can limit the customization to a single page. For more information, see How to: Customize the Layout of an Individual Table By Using a Custom Page Template.

Customizing a data field in the data layer requires several steps. The procedures in this topic address each step of the process.

See a run-time code example of this feature: Run.

See a video that shows this feature: Watch.

Specifying Custom Field Templates in the Data Model

This section describes the steps to associate custom field templates with a data field.

To apply an attribute to a data field

  1. In Solution Explorer, right-click the App_Code folder, and then click Add New Item.

  2. Under Visual Studio installed templates, click Class.

  3. In the Name box, enter the name of the database table (as defined in the data model) that contains the data for the custom field template to display.

    The file name must be the entity class name that represents the table. For example, if the custom field template will display data from the SalesOrderDetail table, you name the file SalesOrderDetail.cs or SalesOrderDetail.vb, and you name the class SalesOrderDetail. The class file that you create will also contain an associated class that lets you apply attributes to data fields.

  4. Add the Partial keyword in Visual Basic or the partial keyword in Visual C# to the class definition to make it a partial class. If you are working in Visual C#, delete the default constructor.

  5. Import the System.Web.DynamicData and System.ComponentModel.DataAnnotations namespaces by using the Imports keyword in Visual Basic or the using keyword in Visual C#, as shown in the following example:

    using System.Web.DynamicData;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.Web.DynamicData
    Imports System.ComponentModel.DataAnnotations 
    
  6. In the class file that you created in steps 1 through 3, create another partial class that will act as the associated metadata class. You can use any name for the class.

    The following example shows how to create an associated metadata class for the SalesOrderDetail field.

    public partial class SalesOrderDetailMetadata
    {
    
    }
    
    Partial Public Class SalesOrderDetailMetadata
    
    End Class 
    
  7. Add the MetadataTypeAttribute attribute to the partial class definition for the data table. For the attribute's parameter, specify the name of the metadata class that you created in the previous step.

    The following example shows how to apply the attribute to connect the partial SalesOrderDetail class to its associated metadata class.

    [MetadataType(typeof(SalesOrderDetailMetadata))]
    public partial class SalesOrderDetail 
    {
    
    }
    
    <MetadataType(GetType(SalesOrderDetailMetadata))> _
    Partial Public Class SalesOrderDetail 
    
    End Class
    
  8. In the associated metadata class, create a public property that has a name that matches the data field that you want to customize.

  9. Apply the UIHintAttribute attribute to the property, specifying the name of the custom field template to use for display and editing

    The Object type is used as a placeholder type in the metadata class to represent the data field. Dynamic Data infers the actual type from the data model at run time.

    public partial class SalesOrderDetailMetadata
    {    
        [UIHint("CustomFieldTemplate")]
        public object OrderQty;
    }
    
    Partial Public Class SalesOrderDetailMetadata
        <UIHint("CustomFieldTemplate")> _
        Public OrderQty As Object
    End Class 
    
  10. Save and close the class file.

Creating Custom Field Templates

Field templates are user controls that Dynamic Data uses to render UI for displaying and editing data fields. This section describes the steps to create a custom field template to render the UI for displaying a data field.

To create a custom field template for display

  1. In Solution Explorer, right-click the DynamicData\FieldTemplates folder, and then click Add New Item.

  2. Under Visual Studio installed templates, click Dynamic Data Field.

  3. In the Name box, enter a name for the custom field template. You can use any name that is not already in use. Make sure that you select the Place the code in separate file box.

  4. Click Add.

    Visual Studio creates two field templates, one for display and one for editing. For example, if the name that you entered was CustomFieldTemplate.ascx, Visual Studio creates CustomFieldTemplate.ascx and CustomFieldTemplate_Edit.ascx. The first template renders the UI for displaying the data field, and the second template renders the UI for editing the data field.

  5. If you want to customize the display of a data field, open the display user control file and add your customization.

    The following example shows a customized field template for displaying data. In the example, the Literal control, which is provided by default in the Dynamic Data Field template, is replaced with a Label control whose Text property is set to the current field value string. You can access the value of the data field by using the FieldValueString property.

    <asp:Label id="Label1" runat="server" 
      Text='<%# FieldValueString %>'>
    </asp:Label> 
    
  6. If required for customization, open the code-behind file for the display field template and add your customizations.

    The following example shows how to synchronize the code with the changes that you made in the markup shown in the previous step. In the code, the Literal1 identifier is replaced with the Label1 identifier to support UI customization for display.

    public override Control DataControl {
      get {return Label1;}
    }
    
    Public Overrides ReadOnly Property DataControl() As Control
      Get
        Return Label1
      End Get
    End Property
    
  7. Override the field template's OnDataBinding method and add code to customize the data field display.

    In the method, you can get the value of the current data field from the control's FieldValue property and then customize the display, as shown in the following example.

    protected override void OnDataBinding(EventArgs e)
    {
    
        if (currentQty < min)
        {
          Label1.ForeColor = System.Drawing.Color.Red;
          Label1.Font.Bold = true;
        }
        else
          if (currentQty > max)
          {
            Label1.ForeColor = System.Drawing.Color.Blue;
            Label1.Font.Bold = true;
           }
        }
      }
    
    Protected Overloads Overrides Sub OnDataBinding( _
    ByVal e As EventArgs)
    
        If currentQty < min Then
          Label1.ForeColor = System.Drawing.Color.Red
          Label1.Font.Bold = True
        ElseIf currentQty > max Then
          Label1.ForeColor = System.Drawing.Color.Blue
          Label1.Font.Bold = True
        End If
      End If
    End Sub
    

The next procedure describes the steps to create a custom field template to render the UI for editing a data field.

To create a custom field template for editing

  1. Open the custom field template whose name ends with the _Edit suffix, and then add your customizations.

    The following example shows markup that adds a CustomValidator control to display custom warning messages if the data entered by the user is invalid. For example, a message is displayed if the data field value is outside certain limits that are defined in the field template. The example sets the validator's Display property to "Dynamic" so that the validation control is displayed only if validation fails. The code sets the ControlToValidate attribute to the ID of the control to validate. It also sets the OnServerValidate attribute to the name of a handler for the validation event.

    <asp:CustomValidator id="CustomValidator1" runat="server" 
      ControlToValidate="TextBox1" Display="Dynamic"
      OnServerValidate="CustomValidation" />
    
  2. Save and close the user control file.

  3. If required for customization, open the code-behind file for the edit field template and add your customizations.

    The following example shows how to create server code for a CustomValidator control. The code compares the value entered by the user to some threshold values and displays an error message if the data is not in the allowed range.

    protected void CustomValidation(object source, 
       ServerValidateEventArgs args)
    {
        // Check if the input is in the allowed range.
        bool result = CheckRange(intUnits);
        // Return result.    
        args.IsValid = result;
    }
    
    Protected Sub CustomValidation( _
      ByVal source As Object, ByVal args As ServerValidateEventArgs)
    
        'Check if the value is in the allowed range.
         Dim result As Boolean = CheckRange(intUnits)
         'Return result.    
         args.IsValid = result
    End Sub
    

Example

The example shows how to use the data model to customize the UI that is rendered to display and edit the OrderQty data field of the SalesOrderDetail table.

The CustomFieldTemplate.ascx field template displays the order quantity by using red foreground if the value is less than the minimum warning threshold. It displays the order quantity by using blue foreground if the value is greater than the maximum warning threshold.

The CustomFieldTemplate_Edit.ascx field template checks the OrderQty value entered by the user against range limits. A custom error message is displayed if the value entered by the user is not in the allowed range.

<%@ Page Language="VB" 
AutoEventWireup="true" CodeFile="CustomAppearanceBehavior.aspx.vb" 
Inherits="CustomAppearanceBehavior" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
        AutoLoadForeignKeys="true" />


    <form id="form1" runat="server">

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
            runat="server" /> 

        <asp:GridView ID="GridView1" 
            runat="server" 
            DataSourceID="GridDataSource" 
            AutoGenerateColumns="false"  
            AutoGenerateEditButton="true"
            AllowPaging="true"
            PageSize="10"
            AllowSorting="true">
            <Columns>
                <asp:DynamicField DataField="OrderQty" />
                <asp:DynamicField DataField="UnitPrice" />
                <asp:DynamicField DataField="ModifiedDate" />
            </Columns>
            <EmptyDataTemplate>
                There are currently no items in this table.
            </EmptyDataTemplate>
       </asp:GridView>
    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource" runat="server"  
        TableName="SalesOrderDetails" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">
    </asp:LinqDataSource>
</body>
</html>
<%@ Page Language="C#" 
AutoEventWireup="true" CodeFile="CustomAppearanceBehavior.aspx.cs" 
Inherits="CustomAppearanceBehavior" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
     <h2>Example: <%=Title%></h2>

     <!-- Enable dynamic behavior. The GridView must be 
     registered with the manager. See code-behind file. -->
    <asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
        AutoLoadForeignKeys="true" />


    <form id="form1" runat="server">

        <!-- Capture validation exceptions -->
        <asp:DynamicValidator ID="ValidatorID" ControlToValidate="GridView1" 
            runat="server" /> 

        <asp:GridView ID="GridView1" 
            runat="server" 
            DataSourceID="GridDataSource" 
            AutoGenerateColumns="false"  
            AutoGenerateEditButton="true"
            AllowPaging="true"
            PageSize="10"
            AllowSorting="true">
            <Columns>
                <asp:DynamicField DataField="OrderQty" />
                <asp:DynamicField DataField="UnitPrice" />
                <asp:DynamicField DataField="ModifiedDate" />
            </Columns>
            <EmptyDataTemplate>
                There are currently no items in this table.
            </EmptyDataTemplate>
       </asp:GridView>
    </form>

    <!-- Connect to the database -->
    <asp:LinqDataSource ID="GridDataSource" runat="server"  
        TableName="SalesOrderDetails" EnableUpdate="true"
        ContextTypeName="AdventureWorksLTDataContext">
    </asp:LinqDataSource>
</body>
</html>
Imports System
Imports System.Collections
Imports System.Configuration
Imports System.Web.DynamicData

Partial Public Class CustomAppearanceBehavior
    Inherits System.Web.UI.Page
    Protected _table As MetaTable

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
        ' Register control with the data manager.
        DynamicDataManager1.RegisterControl(GridView1)
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        ' Get the table entity.
        _table = GridDataSource.GetTable()

        ' Assign title dynamically.
        Title = String.Concat( _
        "Customize Appearance and Behavior of the ", _
        _table.Columns(2).DisplayName, " Data Field")
    End Sub
End Class
using System;
using System.Collections;
using System.Configuration;
using System.Web.DynamicData;

public partial class CustomAppearanceBehavior : System.Web.UI.Page
{
    protected MetaTable _table;

    protected void Page_Init(object sender, EventArgs e)
    {
        // Register control with the data manager.
        DynamicDataManager1.RegisterControl(GridView1);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the table entity.
        _table = GridDataSource.GetTable();

        // Assign title dynamically.

        Title = string.Concat("Customize Appearance and Behavior of the ",
            _table.Columns[2].DisplayName, " Data Field");

    }
}

Compiling the Code

To compile the example code, you need the following:

  • Microsoft Visual Studio 2008 Service Pack 1 or Visual Web Developer 2008 Express Edition Service Pack 1. 

  • The AdventureWorksLT sample database. For information about how to download and install the SQL Server sample database, see Microsoft SQL Server Product Samples: Database on the CodePlex site. Make sure that you install the correct version of the sample database for the version of SQL Server that you are running (Microsoft SQL Server 2005 or Microsoft SQL Server 2008).

  • A dynamic data-driven Web site. This enables you to create a data context for the database and to create the class that contains the data field to customize. For more information, see Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

See Also

Tasks

Walkthrough: Adding Dynamic Data to an Existing Web Site

Concepts

ASP.NET Dynamic Data Field Templates Overview

ASP.NET Dynamic Data Model Overview

ASP.NET Dynamic Data Overview

Reference

FieldTemplateUserControl

Change History

Date

History

Reason

July 2008

Added topic for new feature.

SP1 feature change.