我们有几个ASP.Net dataview列模板,根据用户选择的列动态添加到数据视图中。
这些模板化单元需要处理自定义数据绑定:
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
中处理,因为它不会存在于数据绑定中。
这些控件有更好的模式吗?
有没有办法确保标签在数据绑定之后处理并渲染?
答案 0 :(得分:2)
我已经广泛使用模板化控制,但我还没有找到更好的解决方案。
为什么要在事件处理程序中引用contentLable?
发件人是您可以将其投射到标签的标签,并具有对标签的引用。如下所示。
//add a custom data binding
contentLabel.DataBinding +=
(object sender, EventArgs e ) =>
{
//do custom stuff at databind time
((Label)sender).Text = //bound content
};
然后你应该能够在InstantiateIn中处理标签引用。
请注意我没有测试过这个。
答案 1 :(得分:1)
一种解决方案是使您的模板本身实施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
,因为控件将植根在页面的控制树中并由框架自动处理!