2008-08-27 4 views
4

Nous avons deux modèles de colonne de données ASP.Net qui sont dynamiquement ajoutés à la vue de données en fonction des colonnes sélectionnées par les utilisateurs.Meilleure pratique pour les classes Web.UI.ITemplate ajoutées dynamiquement

Ces cellules ont besoin pour gérer templated DataBindings personnalisés:

public class CustomColumnTemplate: 
    ITemplate 
{ 
    public void InstantiateIn(Control container) 
    { 
     //create a new label 
     Label contentLabel = new Label(); 

     //add a custom data binding 
     contentLabel.DataBinding += 
      (sender, e) => 
      { 
       //do custom stuff at databind time 
       contentLabel.Text = //bound content 
      }; 

     //add the label to the cell 
     container.Controls.Add(contentLabel); 
    } 
} 

... 

myGridView.Columns.Add(new TemplateField 
    { 
     ItemTemplate = new CustomColumnTemplate(), 
     HeaderText = "Custom column" 
    }); 

Tout d'abord cela semble plutôt désordonné, mais il y a aussi une question de ressources. Le Label est généré et ne peut pas être mis au rebut dans le InstantiateIn car il ne serait alors plus là pour le databind.

Y a-t-il un meilleur motif pour ces contrôles?

Existe-t-il un moyen de s'assurer que l'étiquette est éliminée après le databind et rendu?

Répondre

2

J'ai beaucoup travaillé sur le contrôle basé sur des modèles et je n'ai pas trouvé de meilleure solution. Pourquoi faites-vous référence à contentLable dans le gestionnaire d'événements?

L'expéditeur est l'étiquette que vous pouvez utiliser pour l'étiquette et la référence à l'étiquette. Comme ci-dessous. Ensuite, vous devriez pouvoir disposer de la référence d'étiquette dans InstantiateIn.

Veuillez noter que je n'ai pas testé cela.

1

Une solution est de rendre votre modèle lui-même mettre en œuvre IDisposable, puis disposer les contrôles dans la méthode Dispose de votre modèle. Bien sûr, cela signifie que vous avez besoin d'une sorte de collection pour garder une trace des contrôles que vous avez créés. Voici une façon d'aller à ce sujet:

public class CustomColumnTemplate : 
    ITemplate, IDisposable 
{ 
    private readonly ICollection<Control> labels = new List<Control>(); 

    public void Dispose() 
    { 
     foreach (Control label in this.labels) 
      label.Dispose(); 
    } 

    public void InstantiateIn(Control container) 
    { 
     //create a new label 
     Label contentLabel = new Label(); 

     this.labels.Add(contentLabel); 

...

 //add the label to the cell 
     container.Controls.Add(contentLabel); 
    } 
} 

Maintenant, vous êtes toujours confrontés au problème de disposer du modèle. Mais au moins votre modèle sera un consommateur de mémoire responsable, car lorsque vous appelez Dispose sur le modèle, toutes ses étiquettes seront éliminées.

MISE À JOUR

This link on MSDN suggère que peut-être il ne faut pas pour votre modèle pour mettre en œuvre IDisposable parce que les contrôles seront ancrés dans l'arborescence de contrôle de la page et éliminés automatiquement par le cadre!

Questions connexes