Best Practice for Dynamically Added Web.UI.ITemplate Classes

We have several ASP.Net dataview column templates that are dynamically added to the dataview depending on the columns selected by users.

These template cells must handle user data bindings:

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

Firstly, it seems rather dirty, but there is a problem with resources. Label generated and cannot be placed in InstantiateIn , because then it will not be there for data binding.

Is there a better template for these controls?

Is there a way to make sure the label is located after data binding and rendering?

+4
source share
2 answers

I worked a lot with the template, and I did not find a better solution.

Why are you referring to contentLable in the event handler?

The sender is a label that you can put on the label and have a link to the label. Like below.

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

Then you should be able to dispose of the label link in InstantiateIn.

Please note that I have not tested this.

+2
source

One solution is to create the IDisposable template itself, and then remove the controls in your Dispose template. Of course, this means that you need some kind of collection to keep track of the controls you created. Here is one way:

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

Now you are still faced with the problem of deleting the template. But at least your template will be the responsible memory user, because when you call Dispose on the template, all its shortcuts will be placed with it.

UPDATE

This MSDN link suggests that it may not be necessary for your template to implement IDisposable , because the controls will be embedded on the page to manage the tree and be automatically deleted by the wireframe!

+1
source

Source: https://habr.com/ru/post/1276450/


All Articles