Partager via


Comment : personnaliser l'apparence et le comportement d'un champ de données pour les types de données non intrinsèques dans le modèle de données

Mise à jour : Juillet 2008

Dynamic Data ASP.NET vous permet d'utiliser l'attribut System.ComponentModel.DataAnnotations.DataTypeAttribute pour assigner un type de données à un champ de modèle de données. Cela s'avère utile si vous souhaitez assigner un type plus spécifique à ce champ de données que le type CLR déduit par Dynamic Data.

Par exemple, vous pouvez marquer un champ de texte qui contient des adresses de messagerie comme type de messagerie, lequel sera défini comme un type de texte spécifique. Le modèle de champ de texte qui traite le champ peut utiliser les informations fournies par cet attribut pour créer une interface utilisateur spéciale permettant d'afficher et de modifier le type de messagerie. Un champ de texte marqué avec l'attribut EmailAddress() peut être affiché en tant que contrôle System.Web.UI.WebControls.HyperLink.

Vous pouvez également associer un modèle de champ personnalisé à l'attribut UIHint pour spécifier une gestion spécialisée pour les types de données spécifiques. L'attribut DataTypeAttribute vous permet d'utiliser un modèle de champ pour plusieurs types.

La décision d'utiliser l'attribut DataTypeAttribute ou l'attribut UIHint dépend souvent du style souhaité et de la praticité recherchée. Pour plus d'informations sur l'utilisation de la propriété UIHint, consultez Comment : personnaliser les modèles de champs par défaut Dynamic Data ASP.NET.

Cette rubrique décrit comment utiliser l'attribut DataTypeAttribute.

Pour associer des attributs de type de données à un champ de données

  1. Ouvrez le site Web ASP.NET dans lequel vous souhaitez personnaliser des champs de données.

    Remarque :

    Ce site Web doit être configuré pour Dynamic Data.

  2. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le dossier App_Code, puis cliquez sur Ajouter un nouvel élément.

  3. Sous Modèles installés, cliquez sur Classe.

  4. Dans la zone Nom, entrez le nom du fichier.

    Le nom de la classe que vous créez doit correspondre au nom de la classe d'entité qui représente la table. Par exemple, si vous utilisez la table Customer, nommez la classe Customer.

  5. Ajoutez le mot clé Partial dans Visual Basic ou le mot clé partial dans Visual C# à la définition de classe pour en faire une classe partielle.

  6. Ajoutez des références aux espaces de noms System.ComponentModel et System.ComponentModel.DataAnnotations à l'aide du mot clé Imports dans Visual Basic ou du mot clé using dans Visual C#, comme le montre l'exemple suivant :

    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    Imports System.ComponentModel
    Imports System.ComponentModel.DataAnnotations 
    
  7. Ajoutez un accesseur de propriété pour chaque champ de données pour lequel vous souhaitez fournir des attributs.

    L'exemple suivant montre comment créer des accesseurs de propriété pour les trois propriétés qui correspondent aux champs de la table Customer.

    public class CustomerMetaData {
    
        public object PasswordHash { get; set; }
        public object PasswordSalt { get; set; }
        public object ModifiedDate { get; set; }    
    }
    
    Public Class CustomerMetaData
    
        Public PasswordHash As Object
        Public PasswordSalt As Object
        Public ModifiedDate As Object
    End Class
    
  8. Créez une autre classe qui servira de classe de métadonnées associée pour la classe partielle. Vous pouvez lui donner n'importe quel nom du moment que celui-ci n'est pas déjà utilisé. Par exemple, vous pouvez créer une classe qui, en tant que classe de métadonnées associée pour la classe Customer, a le nom CustomerMetaData.

  9. Ajoutez l'attribut MetadataTypeAttribute à la définition de classe partielle. Pour le paramètre de l'attribut, utilisez le nom de la classe de métadonnées associée que vous avez créée à l'étape précédente.

    [MetadataType(typeof(CustomerMetaData))]
    public partial class Customer {
    
    }
    
    <MetadataType(GetType(CustomerMetaData))> _
    Partial Public Class Customer
    
    End Class
    
  10. Dans la classe de métadonnées, ajoutez des attributs DataAnnotations à chaque champ dont vous souhaitez modifier l'affichage ou le comportement.

    L'exemple suivant présente une classe partielle finie pour la table Customer, ainsi qu'une classe de métadonnées associée nommée CustomerMetaData. La classe de métadonnées contient des champs de classe publics qui correspondent aux champs de base de données. Les champs PasswordHash et PasswordSalt sont marqués avec l'attribut ScaffoldColumnattribute, qui a la valeur false. Cela empêche l'affichage des champs par Dynamic Data. Le champ ModifiedDate est marqué avec l'attribut DataType dont la valeur est DataType.Date. Cela spécifie que les données pour ce champ sont affichées en utilisant le format de date courte.

    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    [MetadataType(typeof(CustomerMetaData))]
    public partial class Customer { }
    
    public class CustomerMetaData {
    
       [ScaffoldColumn(false)]
        public object PasswordHash { get; set; }
    
        [ScaffoldColumn(false)]
        public object PasswordSalt { get; set; }
    
        [DataTypeAttribute(DataType.Date)]
        public object ModifiedDate { get; set; }   
    
    }
    
    Imports Microsoft.VisualBasic
    Imports System.ComponentModel
    Imports System.ComponentModel.DataAnnotations
    
    <MetadataType(GetType(CustomerMetaData))> _
    Partial Public Class Customer
    
    End Class
    
    Public Class CustomerMetaData
    
            <ScaffoldColumn(False)> _
        Public PasswordSalt As Object
    
        <DataTypeAttribute(DataType.Date)> _
    Public PasswordSalt As Object
    
        <DataTypeAttribute(DataType.Date)> _
    Public ModifiedDate As Object  
    End Class
    
  11. Pour vous assurer que la classe partielle, la classe de métadonnées et les attributs fonctionnent, exécutez l'application et affichez la table.

Pour modifier un modèle de champ afin d'utiliser des attributs de données personnalisés

  1. Ouvrez le modèle de champ à personnaliser. Si vous souhaitez personnaliser un modèle intégré, ouvrez le modèle de champ qui correspond au type de données auquel Dynamic Data mappe les données.

    Par exemple, si vous personnalisez le modèle de champ utilisé pour afficher des chaînes, ouvrez Text.ascx dans le répertoire DynamicData\FieldTemplates.

  2. Si nécessaire, modifiez le balisage.

  3. Dans le fichier code-behind, substituez la méthode OnDataBinding, appelée lorsque le contrôle du modèle de champ obtient les données à afficher. Dans la méthode, obtenez le ou les attributs pour le champ de données actuel à partir de la propriété MetadataAttributes de la classe FieldTemplateUserControl dont le modèle de champ dérive. Vous pouvez ensuite mettre en forme ou traiter les données selon les attributs avec lesquels le champ est marqué.

    L'exemple suivant présente le code qui peut être utilisé dans le modèle de champ Text.ascx pour afficher les champs de données précédemment modifiés dans cette rubrique.

    Imports System
    Imports System.Data
    Imports System.Configuration
    Imports System.Collections
    Imports System.Collections.Specialized
    Imports System.Linq
    Imports System.Web
    Imports System.Web.Security
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.WebControls.WebParts
    Imports System.Web.UI.HtmlControls
    Imports System.Xml.Linq
    Imports System.Web.DynamicData
    Imports System.ComponentModel.DataAnnotations
    
    Partial Class TextField
        Inherits System.Web.DynamicData.FieldTemplateUserControl
    
        Private Function getNavUrl() As String
            Dim metadata = MetadataAttributes.OfType(Of DataTypeAttribute).FirstOrDefault()
            If (metadata Is Nothing) Then
                Return FieldValueString
            End If
    
            Dim url As String = FieldValueString
    
            Select Case metadata.DataType
    
                Case DataType.Url
                    url = FieldValueString
                    If (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) Or _
                       url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) Then
                        Return url
                    End If
    
                    Return "http://" + FieldValueString
    
                Case DataType.EmailAddress
                    Return "mailto:" + FieldValueString
    
                Case Else
                    Throw New Exception("Unknow DataType")
    
            End Select
    
        End Function
    
    
        Protected Overrides Sub OnDataBinding(ByVal e As System.EventArgs)
            MyBase.OnDataBinding(e)
    
            If (String.IsNullOrEmpty(FieldValueString)) Then
                Return
            End If
    
            Dim metadata = MetadataAttributes.OfType(Of DataTypeAttribute).FirstOrDefault()
    
            If (metadata Is Nothing Or String.IsNullOrEmpty(FieldValueString)) Then
                Dim literal As New Literal()
                literal.Text = FieldValueString
                Controls.Add(literal)
                Return
            End If
    
            If (metadata.DataType = DataType.Url Or _
                metadata.DataType = DataType.EmailAddress) Then
    
                Dim hyperlink As New HyperLink
                hyperlink.Text = FieldValueString
                hyperlink.href = getNavUrl()
                hyperlink.Target = "_blank"
                Controls.Add(hyperlink)
                Return
    
            End If
    
            If (metadata.DataType = DataType.Custom And _
                 String.Compare(metadata.CustomDataType, "BoldRed", True) = 0) Then
                Dim lbl As New Label()
                lbl.Text = FieldValueString
                lbl.Font.Bold = True
                lbl.ForeColor = System.Drawing.Color.Red
                Controls.Add(lbl)
            End If
    
        End Sub
    
    End Class
    
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Xml.Linq;
    using System.Web.DynamicData;
    using System.ComponentModel.DataAnnotations;
    
    public partial class TextField : System.Web.DynamicData.FieldTemplateUserControl {
    
        string getNavUrl() {
    
            var metadata = MetadataAttributes.OfType<DataTypeAttribute>().FirstOrDefault();
            if (metadata == null)
                return FieldValueString; 
    
            switch (metadata.DataType) {
    
                case DataType.Url:
                    string url = FieldValueString;
                    if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
                        url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                        return url;
    
                    return "http://" + FieldValueString;
    
    
                case DataType.EmailAddress:
                    return "mailto:" + FieldValueString;
    
                default:
                    throw new Exception("Unknown DataType");
            }
        }
    
        protected override void OnDataBinding(EventArgs e) {
            base.OnDataBinding(e);
    
            if (string.IsNullOrEmpty(FieldValueString))
                return;
    
            var metadata = MetadataAttributes.OfType<DataTypeAttribute>().FirstOrDefault();
    
            if (metadata == null || string.IsNullOrEmpty(FieldValueString)) {
                Literal literal = new Literal();
                literal.Text = FieldValueString;
                Controls.Add(literal);
                return;
            }
    
            if (metadata.DataType == DataType.Url ||
                metadata.DataType == DataType.EmailAddress) {
    
                HyperLink hyperlink = new HyperLink();
                hyperlink.Text = FieldValueString;
                hyperlink.href = getNavUrl();
                hyperlink.Target = "_blank";
                Controls.Add(hyperlink);
                return;
            }
    
            if (metadata.DataType == DataType.Custom &&
               string.Compare(metadata.CustomDataType, "BoldRed", true) == 0) {
                Label lbl = new Label();
                lbl.Text = FieldValueString;
                lbl.Font.Bold = true;
                lbl.ForeColor = System.Drawing.Color.Red;
                Controls.Add(lbl);
            }
    
        }
    
    }
    

    Le code obtient les attributs pour le champ actuel. Il les teste et exécute une logique différente, selon attribut avec lequel le champ a été marqué. Par exemple, le code peut déterminer que le champ est marqué avec l'attribut BoldRed personnalisé en testant Custom(), puis en testant que la propriété CustomDataType() est "BoldRed". Si c'est le cas, le code crée une interface utilisateur permettant d'afficher les données dans un contrôle Label en style texte rouge.

Exemple

L'exemple suivant montre comment personnaliser l'apparence et le comportement d'un champ de données pour les types de données non intrinsèques. Le code personnalise la manière dont Dynamic Data affiche les champs EmailAddress, SalesPerson et LastName à partir de la table Customer de la base de données AdventureWorksLT.

Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations

<MetadataType(GetType(CustomerMetaData))> _
Partial Public Class Customer

End Class


Public Class CustomerMetaData

    <ScaffoldColumn(False)> _
    Public PasswordHash As Object

    <ScaffoldColumn(False)> _
    Public PasswordSalt As Object

    <DataTypeAttribute(DataType.Date)> _
    Public ModifiedDate As Object

    <DataTypeAttribute(DataType.EmailAddress)> _
    Public EmailAddress As Object

    <DataTypeAttribute(DataType.Url)> _
    Public SalesPerson As Object


    <DataTypeAttribute("BoldRed")> _
    <DisplayName("Last")> _
    Public ReadOnly Property LastName() As Object
        Get
            Return ""
        End Get
    End Property

End Class
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(CustomerMetaData))]
public partial class Customer {
}

public class CustomerMetaData {

    [ScaffoldColumn(false)]
    public object PasswordHash { get; set; }

    [ScaffoldColumn(false)]
    public object PasswordSalt { get; set; }

    [DataTypeAttribute(DataType.Date)]
    public object ModifiedDate { get; set; }

    [DataTypeAttribute(DataType.EmailAddress)]
    public object EmailAddress { get; set; }

    [DataTypeAttribute(DataType.Url)]
    public object SalesPerson { get; set; }

    [DisplayName("Last")]
    [DataTypeAttribute("BoldRed")]
    [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$", 
        ErrorMessage = "Characters are not allowed.")]

    public object LastName { get; set; }
} 

Dans l'exemple, l'attribut DataTypeAttribute a la valeur EmailAddress() pour la propriété EmailAddress. L'attribut DataTypeAttribute a la valeur Url() pour la propriété SalesPerson, et l'attribut DataTypeAttribute a la valeur BoldRed pour la propriété LastName. BoldRed est défini en tant que propriété personnalisée.

Compilation du code

Pour compiler cet exemple de code, vous avez besoin des éléments suivants :

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

  • L'exemple de base de données AdventureWorksLT. Pour plus d'informations sur le téléchargement et l'installation de l'exemple de base de données SQL Server, consultez Exemples de produits Microsoft SQL Server : Base de données (en anglais) sur le site CodePlex. Prenez soin d'installer la version appropriée de l'exemple de base de données pour la version de SQL Server que vous exécutez (Microsoft SQL Server 2005 ou Microsoft SQL Server 2008).

  • Un site Web dynamique piloté par les données. Cela vous permet de créer un contexte de données pour la base de données et de créer la classe qui contient le champ de données à personnaliser et les méthodes à substituer. Pour plus d'informations, consultez Walkthrough: Creating a New Dynamic Data Web Site using Scaffolding.

Voir aussi

Tâches

Comment : personnaliser les modèles de champs par défaut Dynamic Data ASP.NET

Historique des modifications

Date

Historique

Raison

Juillet 2008

Ajout d'une rubrique.

Modifications de fonctionnalités dans le SP1.