【问题标题】:Best practice for dynamically added Web.UI.ITemplate classes动态添加的 Web.UI.ITemplate 类的最佳实践
【发布时间】:2010-09-06 23:54:45
【问题描述】:

我们有几个 ASP.Net 数据视图列模板,它们根据用户选择的列动态添加到数据视图中。

这些模板化单元需要处理自定义数据绑定:

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

首先这看起来相当混乱,但也存在资源问题。 Label 已生成,不能在 InstantiateIn 中处理,因为那样它就不会在那里进行数据绑定。

这些控件有更好的模式吗?

有没有办法确保标签在数据绑定和渲染之后被释放?

【问题讨论】:

    标签: .net asp.net


    【解决方案1】:

    我已经广泛使用模板化控件,但没有找到更好的解决方案。

    为什么要在事件处理程序中引用 contentLable?

    发件人是标签,您可以将其转换为标签并具有对标签的引用。如下所示。

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

    那么你应该可以在 InstantiateIn 中处理标签引用。

    请注意,我没有对此进行测试。

    【讨论】:

      【解决方案2】:

      一种解决方案是让您的模板自身实现IDisposable,然后在模板的Dispose 方法中处理控件。当然,这意味着您需要某种集合来跟踪您创建的控件。这是一种解决方法:

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

      现在您仍然面临处置模板的问题。但至少您的模板将是一个负责任的内存使用者,因为当您在模板上调用 Dispose 时,它的所有标签都将随它一起处理。

      更新

      This link on MSDN 建议您的模板可能没有必要实现IDisposable,因为控件将植根于页面的控件树并由框架自动释放!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多