Partager via


Développement de contrôles serveur Web liés aux données personnalisés pour ASP.NET 2.0

Mise à jour : novembre 2007

Les contrôles serveur Web liés aux données ASP.NET fournissent une interface utilisateur pour une source de données qui représente une collection d'enregistrements ou d'éléments. Les contrôles serveur Vue d'ensemble du contrôle serveur Web GridView, Vue d'ensemble du contrôle serveur Web DataList et Vue d'ensemble du contrôle serveur Web Repeater sont des exemples de contrôles serveur Web liés aux données. Pour plus d'informations sur les contrôles liés aux données fournis avec ASP.NET, consultez Vue d'ensemble des contrôles serveur Web liés aux données ASP.NET.

Dans ASP.NET version 2.0, un nouveau modèle de source de données vous permet de lier des contrôles liés aux données aux contrôles de source de données, ce qui permet de déplacer des opérations communes sur les données, telles que la pagination, le tri et la suppression, hors du contrôle lié aux données lui-même. Ce modèle génère un contrôle lié aux données plus flexible pour les développeurs de pages et augmente le niveau de réutilisabilité.

Cette rubrique présente les étapes de base qui sont requises pour implémenter un contrôle serveur lié aux données ASP.NET 2.0 personnalisé. Pour plus d'informations sur l'architecture générale et les implémentations de contrôles personnalisés, consultez Développement de contrôles serveur ASP.NET personnalisés et Procédure pas à pas : développement et utilisation d'un contrôle serveur personnalisé. Pour plus d'informations sur le développement de contrôles liés aux données compatibles ASP.NET 1.1, consultez Développement de contrôles serveur Web liés aux données personnalisés pour ASP.NET 1.1 et Procédure pas à pas : création d'un contrôle Web ASP.NET lié aux données personnalisé pour ASP.NET 1.1. Pour plus d'informations sur les contrôles de source de données, consultez Vue d'ensemble des contrôles de source de données.

À quel moment créer un contrôle lié aux données personnalisé ?

Avant de créer votre propre contrôle lié aux données personnalisé, examinez les fonctions des contrôles liés aux données déjà fournis avec ASP.NET. Les contrôles existants peuvent satisfaire vos besoins ou vous pouvez décider de créer un contrôle personnalisé qui étend un contrôle existant présentant déjà la plupart des fonctionnalités dont vous avez besoin. Pour plus d'informations sur les contrôles liés aux données fournis avec ASP.NET, consultez Vue d'ensemble des contrôles serveur Web liés aux données ASP.NET.

Voici quelques raisons pour lesquelles vous pouvez décider de créer un contrôle lié aux données personnalisé :

  • Vos besoins particuliers nécessitent une interface utilisateur personnalisée, des fonctionnalités de tri des données personnalisées ou des fonctionnalités d'édition de données personnalisées qui ne sont pas disponibles dans les contrôles liés aux données existants.

  • Vous souhaitez créer un contrôle lié aux données personnalisé qui est précompilé et redistribuable.

  • Vous souhaitez étendre les fonctionnalités d'un contrôle lié aux données qui est déjà fourni avec ASP.NET.

  • Vous souhaitez créer un contrôle lié aux données avec un concepteur personnalisé qui s'adapte à vos besoins spécifiques.

Fonctionnalités de base d'un contrôle lié aux données personnalisé

En dérivant de l'une des classes de base de contrôles liés aux données, telles que la classe DataBoundControl ou CompositeDataBoundControl, votre contrôle lié aux données personnalisé hérite automatiquement de nombreuses fonctionnalités intégrées, notamment :

  • Prise en charge des sources de données pour l'interface IDataSource et sa classe DataSourceView connexe, qui fournit des affichages de données nommés, la capacité d'interroger les types d'opérations pris en charge par le magasin de données ainsi que la fonction de chargement des données à la demande.

  • Prise en charge des sources de données pour les interfaces IEnumerable ou IListSource génériques.

  • Prise en charge des expressions de liaison de données, ce qui permet aux développeurs de pages de créer des liaisons entre une propriété exposée et spécialement marquée de votre contrôle et une source de données. Pour plus d'informations sur les expressions de liaison de données, consultez Vue d'ensemble des expressions de liaison de données.

  • Prise en charge de la liaison de données automatique qui appelle la logique de liaison de données aussi tard que possible pendant le cycle de vie de la page et uniquement si nécessaire, plutôt que pour chaque publication. Une fois qu'une page a soumis la première demande de liaison de données, les demandes suivantes essaient de récupérer les données de l'état d'affichage. Les performances sont ainsi améliorées en évitant d'avoir à établir à nouveau la connexion à la source de données à chaque demande.

Utilisation des fonctionnalités de design disponibles

Il existe des fonctionnalités de design disponibles pour tous les contrôles serveur Web que vous pouvez envisager pour votre contrôle lié aux données personnalisé. Vous pouvez créer une classe de concepteur et des modèles de contrôle pour votre contrôle personnalisé. Ces fonctionnalités sont appelées lorsque votre contrôle est utilisé au moment du design sur une aire de conception visuelle, par exemple le mode Design dans Visual Studio.

La création d'un Concepteur de contrôles peut augmenter considérablement la facilité d'utilisation de votre contrôle personnalisé au moment du design en fournissant une interface de design qui permet aux développeurs de pages de personnaliser les propriétés du contrôle. Pour obtenir une vue d'ensemble des Concepteurs de contrôles ASP.NET, consultez Vue d'ensemble des Concepteurs de contrôles ASP.NET. Pour obtenir des exemples, consultez HierarchicalDataBoundControlDesigner et Procédure pas à pas : création d'un Concepteur de contrôles de base pour un contrôle serveur Web.

En créant un contrôle basé sur un modèle, vous offrez aux développeurs de pages la souplesse pour spécifier les contrôles et le balisage qui définissent l'interface utilisateur du contrôle. Pour obtenir un exemple de contrôle basé sur un modèle personnalisé, consultez Contrôle serveur basé sur des modèles, exemple.

Implémentation d'un contrôle lié aux données personnalisé dans ASP.NET 2.0

Le tableau suivant résume les étapes qui sont spécifiques à l'implémentation d'un contrôle serveur lié aux données personnalisé dans ASP.NET 2.0. Des informations plus détaillées sur chacune des étapes d'implémentation figurent à la suite du tableau.

Étape

Résumé de l'étape

Choisir une classe de base de contrôles liés aux données.

Étendez une classe de contrôles liés aux données existante qui fournit déjà la plupart des fonctionnalités dont vous avez besoin ou dérivez de l'une des classes de contrôles liés aux données de base.

Exposer des propriétés de liaison de données.

Configurez votre contrôle personnalisé pour exposer des propriétés de liaison de données qui s'ajoutent aux propriétés de liaison de données minimales requises exposées par les classes de contrôles liés aux données de base.

Initier la récupération des données.

  • Récupérez les données que le développeur de pages a assignées à votre contrôle en effectuant les opérations suivantes :

  • Substituez la méthode PerformSelect de la classe de contrôles liés aux données de base.

  • Appelez la méthode GetData de la classe de contrôles liés aux données de base pour récupérer l'affichage de source de données du contrôle.

  • Appelez la méthode Select de l'objet DataSourceView pour initier la récupération des données et spécifier la méthode de rappel qui recevra les données.

Gérer les données récupérées.

Fournissez la méthode de rappel que vous avez spécifiée comme paramètre dans la méthode Select. La méthode de rappel doit avoir un seul paramètre de type IEnumerable pour recevoir les données. Si un traitement des données est requis par votre contrôle, il doit avoir lieu dans cette méthode de rappel.

Créer les objets d'interface utilisateur représentant les données

Fournissez une substitution de la méthode PerformDataBinding. Vous devez exécuter les tâches suivantes dans cette méthode :

  • Appelez la méthode PerformDataBinding pour autoriser l'exécution de tout autre code qui dépend de cette méthode.

  • Énumérez la collecte de données et créez des contrôles enfants qui représenteront les données dans l'affichage d'interface utilisateur.

Choisir une classe de base de contrôles liés aux données

Les développeurs de contrôles peuvent étendre l'une des classes de base de contrôles liés aux données disponibles pour créer un contrôle lié aux données personnalisé. Le tableau suivant fournit une liste de classes de base liées aux données qui sont disponibles dans ASP.NET 2.0. Examinez les descriptions de chaque classe, puis identifiez la classe de base qui répond le mieux aux impératifs de votre contrôle lié aux données personnalisé. Pour plus d'informations sur chaque classe de base pour les contrôles liés aux données et les exemples d'implémentation, consultez la documentation de référence pour chaque classe. Pour plus d'informations sur les contrôles liés aux données fournis par ASP.NET, consultez Vue d'ensemble des contrôles serveur Web liés aux données ASP.NET.

Classe

Description

BaseDataBoundControl

  • Il s'agit de la classe de base pour tous les contrôles liés aux données qui exécute la liaison de données et la validation de toutes les données liées.

DataBoundControl

Il s'agit de la classe liée aux données de base pour générer des contrôles liés aux données standard. DataBoundControl effectue les opérations suivantes :

  • Fournit une implémentation de base partagée par tous les contrôles liés aux données.

  • Contient la logique pour communiquer avec les contrôles de source de données et les conteneurs de données.

  • Sert de base pour les contrôles liés aux données, tels que TreeView et ListControl.

ListControl

  • Il s'agit de la classe de base pour les contrôles List qui étend la classe DataBoundControl. Elle fournit une collection d'Items et des fonctions avancées de rendu de disposition.

CompositeDataBoundControl

  • Il s'agit de la classe de base qui étend la classe DataBoundControl, en fournissant les fonctionnalités suivantes :

  • Implémente le code classique requis par les contrôles composites, y compris le code qui restaure la hiérarchie des contrôles enfants du contrôle à partir de l'état d'affichage après une publication.

  • Crée une liaison à une source de données IEnumerable et énumère les données pour générer une arborescence du contrôle.

  • Sert de base pour les contrôles liés aux données, tels que GridView et DetailsView.

HierarchicalDataBoundControl

  • Il s'agit de la classe de base pour les contrôles qui affichent leurs données sous forme hiérarchique. Elle sert de base pour les contrôles basés sur arborescence liés aux données, tels que TreeView et Menu.

Propriétés de liaison de données fournies

Les classes de contrôles liés aux données de base fournissent déjà les propriétés de liaison de données exposées nécessaires pour permettre à un développeur de pages de lier une source de données à un contrôle. Aucun travail supplémentaire n'est exigé de la part du créateur du contrôle. En dérivant de DataBoundControl, par exemple, un contrôle personnalisé hérite de trois propriétés de liaison de données exposées : DataSourceID, DataSource et DataMember. Un développeur de pages peut ensuite spécifier la source des données à laquelle le contrôle sera lié en définissant la valeur de la propriété DataSource ou DataSourceID.

La propriété DataSourceID permet au développeur de pages de spécifier l'ID d'un contrôle qui représente la source de données à partir de laquelle le contrôle lié aux données récupère ses données.

La propriété DataSource permet au développeur de pages de lier directement un contrôle lié aux données aux objets de données des deux types suivants :

  • Objet qui implémente l'interface IEnumerable, tel qu'un objet Array, ArrayList ou Hashtable.

  • Objet qui implémente l'interface IListSource, tel qu'un objet DataSet.

  • Des propriétés de liaison de données supplémentaires, telles que la propriété DataMember, permettent au développeur de pages de spécifier la partie de la collecte de données à laquelle le contrôle doit être lié.

  • Pour plus d'informations sur les propriétés de liaison de données exposées fournies par chaque classe de contrôles liés aux données ou classe de base liée aux données, consultez la documentation de référence pour chaque classe.

Exposition de propriétés de liaison de données personnalisées

Lorsque vous exposez vos propres propriétés de liaison de données personnalisées dans un contrôle personnalisé ou substituez des propriétés de liaison de données existantes, vous devez appeler la méthode OnDataPropertyChanged si le contrôle a déjà été initialisé. Cela force le contrôle lié aux données à créer une nouvelle liaison aux données afin qu'il puisse utiliser le nouveau paramètre de propriété de liaison de données.

L'exemple de code suivant illustre une propriété qui appartient à une classe de contrôles liés aux données dérivée. L'exemple montre comment un contrôle lié aux données peut appeler la méthode OnDataPropertyChanged si une propriété qui identifie une source de données est modifiée après l'initialisation du contrôle lié aux données.

Inherits DataBoundControl

Public Property DataTextField() As String
    Get
        Dim o As Object = ViewState("DataTextField")
        If o Is Nothing Then
            Return String.Empty
        Else
            Return CStr(o)
        End If
    End Get
    Set(ByVal value As String)
        ViewState("DataTextField") = value
        If (Initialized) Then
            OnDataPropertyChanged()
        End If
    End Set
End Property
public class SimpleDataBoundColumn : DataBoundControl
{
    public string DataTextField
    {
        get
        {
            object o = ViewState["DataTextField"];
            return ((o == null) ? string.Empty : (string)o);
        }
        set
        {
            ViewState["DataTextField"] = value;
            if (Initialized)
            {
                OnDataPropertyChanged();
            }
        }
    }

Initier la récupération des données

La récupération des données est initiée dans une substitution de la méthode PerformSelect héritée par le contrôle lié aux données de base de votre contrôle. Dans cette substitution, vous appelez pour récupérer les données et spécifier une méthode de rappel qui gérera les données une fois retournées.

Pour récupérer les données, effectuez les tâches suivantes dans la méthode PerformSelect substituée :

  1. Déterminez si le développeur de pages a utilisé la propriété DataSource ou la propriété DataSourceID pour définir les données à lier au contrôle. Pour ce faire, vérifiez la propriété IsBoundUsingDataSourceID. Par exemple, un paramètre false pour la propriété IsBoundUsingDataSourceID indique que la propriété DataSource a été utilisée pour spécifier la source de données.

  2. Si le développeur de pages a défini la propriété DataSource, une étape supplémentaire est requise : appelez la méthode OnDataBinding.

  3. Appelez la méthode GetData pour récupérer l'objet DataSourceView associé au contrôle lié aux données.

  4. Appelez la méthode Select de l'DataSourceView récupéré pour initier la récupération des données et spécifier la méthode de rappel qui gérera les données récupérées. La méthode Select fonctionnant de façon asynchrone, un autre traitement est autorisé pendant la récupération des données.

  5. Indiquez l'achèvement des tâches PerformSelect en affectant la valeur false à la propriété RequiresDataBinding, puis en appelant la méthode MarkAsDataBound.

  6. Déclenchez l'événement OnDataBound.

L'exemple de code suivant illustre les tâches de récupération des données précédentes comme étant terminées dans une substitution de la méthode PerformSelect.

Protected Overrides Sub PerformSelect()
    ' Call OnDataBinding here if bound to a data source using the
    ' DataSource property (instead of a DataSourceID), because the
    ' databinding statement is evaluated before the call to GetData.       
    If Not IsBoundUsingDataSourceID Then
        OnDataBinding(EventArgs.Empty)
    End If

    ' The GetData method retrieves the DataSourceView object from  
    ' the IDataSource associated with the data-bound control.            
    GetData().Select(CreateDataSourceSelectArguments(), _
        AddressOf OnDataSourceViewSelectCallback)

    ' The PerformDataBinding method has completed.
    RequiresDataBinding = False
    MarkAsDataBound()

    ' Raise the DataBound event.
    OnDataBound(EventArgs.Empty)

End Sub
protected override void PerformSelect()
{
    // Call OnDataBinding here if bound to a data source using the
    // DataSource property (instead of a DataSourceID), because the
    // databinding statement is evaluated before the call to GetData.       
    if (!IsBoundUsingDataSourceID)
    {
        this.OnDataBinding(EventArgs.Empty);
    }

    // The GetData method retrieves the DataSourceView object from  
    // the IDataSource associated with the data-bound control.            
    GetData().Select(CreateDataSourceSelectArguments(),
        this.OnDataSourceViewSelectCallback);

    // The PerformDataBinding method has completed.
    RequiresDataBinding = false;
    MarkAsDataBound();

    // Raise the DataBound event.
    OnDataBound(EventArgs.Empty);
}

Gérer les données récupérées

Créez votre propre méthode de rappel pour accepter les données récupérées. Il s'agit de la méthode de rappel que vous avez spécifiée lorsque la méthode Select a été appelée dans la substitution de la méthode PerformSelect. La méthode de rappel est requise pour contenir uniquement un seul paramètre du type IEnumerable. Dans votre méthode de rappel, vous pouvez procéder à tout traitement des données retournées, si votre contrôle l'exige. En tant que dernière étape, appelez la méthode PerformDataBinding.

L'exemple de code suivant illustre une méthode de rappel qui a un paramètre de type IEnumerable et appelle la méthode PerformDataBinding.

Private Sub OnDataSourceViewSelectCallback(ByVal retrievedData As IEnumerable)
    ' Call OnDataBinding only if it has not already been 
    ' called in the PerformSelect method.
    If IsBoundUsingDataSourceID Then
        OnDataBinding(EventArgs.Empty)
    End If
    ' The PerformDataBinding method binds the data in the  
    ' retrievedData collection to elements of the data-bound control.
    PerformDataBinding(retrievedData)

End Sub
private void OnDataSourceViewSelectCallback(IEnumerable retrievedData)
{
    // Call OnDataBinding only if it has not already been 
    // called in the PerformSelect method.
    if (IsBoundUsingDataSourceID)
    {
        OnDataBinding(EventArgs.Empty);
    }
    // The PerformDataBinding method binds the data in the  
    // retrievedData collection to elements of the data-bound control.
    PerformDataBinding(retrievedData);
}

Créer les objets d'interface utilisateur représentant les données

Dans une substitution de la méthode PerformDataBinding, vous créez les contrôles enfants qui représenteront les données. La collecte de données est énumérée, et les contrôles enfants sont créés et leurs propriétés définies selon chaque élément de données. En ajoutant les nouveaux contrôles enfants à la collection Controls du contrôle, les contrôles enfants seront rendus pour vous. La hiérarchie des contrôles est rendue pendant la méthode Render héritée du contrôle. Vous pouvez choisir de substituer la méthode Render pour effectuer un rendu spécial requis par votre contrôle personnalisé, tel que l'ajout d'éléments HTML supplémentaires ou un rendu spécial pour l'affichage en mode Design.

Pour créer les objets d'interface utilisateur représentant les données, substituez la méthode PerformDataBinding et effectuez les tâches suivantes :

  1. Appelez la méthode PerformDataBinding pour autoriser l'exécution de tout autre code qui dépend de cette méthode.

  2. Énumérez la collecte de données et créez des contrôles enfants qui représenteront les données dans l'affichage d'interface utilisateur. Ajoutez chaque contrôle enfant à la collection du contrôle en appelant la méthode Add du contrôle.

  • L'exemple de code suivant illustre la substitution de la méthode PerformDataBinding. La méthode PerformDataBinding est appelée pour autoriser l'exécution de tout autre code qui dépend de cette méthode. La collecte de données est énumérée et les contrôles enfants sont créés pour représenter les données dans l'affichage d'interface utilisateur.
        Protected Overrides Sub PerformDataBinding(ByVal retrievedData As IEnumerable)
            MyBase.PerformDataBinding(retrievedData)

            ' Verify data exists.
            If Not (retrievedData Is Nothing) Then
                Dim tbl As New Table()
                Dim row As TableRow
                Dim cell As TableCell
                Dim dataStr As String = String.Empty

                Dim dataItem As Object
                For Each dataItem In retrievedData
                    ' If the DataTextField was specified get the data
                    ' from that field, otherwise get the data from the first field. 
                    If DataTextField.Length > 0 Then
                        dataStr = DataBinder.GetPropertyValue(dataItem, DataTextField, Nothing)
                    Else
                        Dim props As PropertyDescriptorCollection = TypeDescriptor.GetProperties(dataItem)
                        If props.Count >= 1 Then
                            If Nothing <> props(0).GetValue(dataItem) Then
                                dataStr = props(0).GetValue(dataItem).ToString()
                            End If
                        End If
                    End If

                    row = New TableRow()
                    tbl.Rows.Add(row)
                    cell = New TableCell()
                    cell.Text = dataStr
                    row.Cells.Add(cell)
                Next dataItem

                Controls.Add(tbl)
            End If

        End Sub
    End Class
End Namespace
protected override void PerformDataBinding(IEnumerable retrievedData)
{
    base.PerformDataBinding(retrievedData);

    // Verify data exists.
    if (retrievedData != null)
    {
        Table tbl = new Table();
        TableRow row;
        TableCell cell;
        string dataStr = String.Empty;

        foreach (object dataItem in retrievedData)
        {
            // If the DataTextField was specified get the data
            // from that field, otherwise get the data from the first field. 
            if (DataTextField.Length > 0)
            {
                dataStr = DataBinder.GetPropertyValue(dataItem,
                    DataTextField, null);
            }
            else
            {
                PropertyDescriptorCollection props =
                        TypeDescriptor.GetProperties(dataItem);
                if (props.Count >= 1)
                {
                    if (null != props[0].GetValue(dataItem))
                    {
                        dataStr = props[0].GetValue(dataItem).ToString();
                    }
                }
            }

            row = new TableRow();
            tbl.Rows.Add(row);
            cell = new TableCell();
            cell.Text = dataStr;
            row.Cells.Add(cell);
        }

        this.Controls.Add(tbl); 
    }
}

Génération de votre contrôle serveur personnalisé

Pour plus d'informations sur la génération de votre contrôle serveur Web lié aux données personnalisé et son utilisation dans une page Web, consultez Exemples de création de contrôles serveur personnalisés.

Voir aussi

Tâches

Procédure pas à pas : création d'un contrôle Web ASP.NET lié aux données personnalisé pour ASP.NET 2.0

Procédure pas à pas : développement et utilisation d'un contrôle serveur personnalisé

Concepts

Vue d'ensemble des contrôles serveur Web liés aux données ASP.NET

Attributs de métadonnées pour des contrôles serveur personnalisés

Vue d'ensemble des Concepteurs de contrôles ASP.NET

Référence

HierarchicalDataBoundControlDesigner

Autres ressources

Développement de contrôles serveur ASP.NET personnalisés