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
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.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le dossier App_Code, puis cliquez sur Ajouter un nouvel élément.
Sous Modèles installés, cliquez sur Classe.
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.
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.
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
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
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.
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
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
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
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.
Si nécessaire, modifiez le balisage.
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. |