2008-08-27 6 views
4

Wir haben einige ASP.Net-dataview-Spaltenvorlagen, die dynamisch zur Datenansicht hinzugefügt werden, abhängig von den von Benutzern ausgewählten Spalten.Best Practice für dynamisch hinzugefügte Web.UI.ITemplate-Klassen

benötigen Diese Templat Zellen individuelle Databindings zu handhaben:

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" 
    }); 

Zunächst scheint dies eher chaotisch, aber es gibt auch eine Ressourcenfrage. Die Label wird erzeugt, und kann nicht in der InstantiateIn entsorgt werden, weil sie dann nicht zur Datenerfassung da wäre.

Gibt es ein besseres Muster für diese Kontrollen?

Gibt es eine Möglichkeit, um sicherzustellen, dass das Etikett nach der Datenbank und rendern?

Antwort

2

Ich habe intensiv mit Templatsteuerung gearbeitet und ich habe keine bessere Lösung gefunden.

Warum verweisen Sie die ContentLabel in der Ereignisbehandlungsroutine?

Der Absender ist das Etikett, das Sie auf das Etikett werfen können und den Verweis auf das Etikett haben. Wie unten.

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

Dann sollten Sie in der Lage sein, die Etikettenreferenz in InstantiateIn zu entsorgen.

Bitte beachten Sie, dass ich dies nicht getestet habe.

1

Eine Lösung ist die Vorlage selbst IDisposable, implementieren zu machen und dann Dispose Verfahren die Kontrollen in der Vorlage der entsorgen. Das bedeutet natürlich, dass Sie eine Art Sammlung benötigen, um die von Ihnen erstellten Steuerelemente nachzuverfolgen. Hier ist eine Möglichkeit, darüber zu gehen:

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); 
    } 
} 

Jetzt sind Sie immer noch mit dem Problem der Entsorgung der Vorlage konfrontiert. Aber zumindest Ihre Vorlage wird ein verantwortungsvoller Speicherverbraucher sein, denn wenn Sie Dispose auf der Vorlage aufrufen, werden alle seine Etiketten mit ihm entsorgt.

UPDATE

This link on MSDN legt nahe, dass es vielleicht nicht notwendig, für die Vorlage ist IDisposable zu implementieren, da die Steuerelemente in der Seite Steuerbaum und automatisch angeordnet durch den Rahmen verwurzelt werden!