我正在尝试将模板添加到包含Label和TextBox的简化复合控件中。我希望我的标记看起来像这样:
<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!">
<TestTemplate>
<i>
<%# Container.Title) %></i>
<br />
<%# Container.Text %>
</TestTemplate>
</test:FormItem>
我有一个templateContainer类,它具有TextBox和Label的属性。
public class TemplateContainer : WebControl, INamingContainer
{
public TextBox Text { get { return m_item.Text; } }
public Label Title { get { return m_item.Title; } }
private FormItem m_item;
public TemplateContainer(FormItem item)
{
m_item = item;
}
}
在主FormItem类中,我有一个从CreateChildControls()调用的CreateControlHierarchy()方法:
protected virtual void CreateControlHierarchy()
{
m_itemTemplateContainer = new TemplateContainer(this);
TestTemplate.InstantiateIn(m_itemTemplateContainer);
Controls.Add(m_itemTemplateContainer);
}
我想要的是模板呈现实际控件。相反,它在控件上调用ToString()并显示System.Web.UI.WebControls.Label和System.Web.UI.WebControls.TextBox。有没有办法让模板将控件添加到它的集合中而不是只调用它们上的ToString()?
注意:我也尝试将文本框和标签添加到容器的控件集合中,它们执行相同的操作。
答案 0 :(得分:1)
确定。所以我尝试了一些东西,然后我找到了一个好的解决方案。
首先,我尝试在数据绑定表达式中使用方法,然后跟踪容器的Control集合中文本框或标签的位置。但是,CompiledTemplateBuilder(这是.Net内部为标记中指定的ITemplates构建的)将两个绑定表达式之前和之后的所有标记放入一个DataBoundLiteral控件中,并且在调用该方法时已经构建了Control集合。
创建一个新的WebControl是什么工作,它作为复合控件中控件的占位符。它有一个属性Control,当设置时,它将控件添加到它的Controls Collection。
public class FormItemPlaceHolder : WebControl, INamingContainer
{
public WebControl Control
{
get
{
if(Controls.Count == 0)
return null;
return Controls[0] as WebControl;
}
set
{
if (Controls.Count != 0)
Controls.Clear();
Controls.Add(value);
}
}
}
然后在标记中,我创建了一个这种类型的控件,并将它的Control属性绑定到容器中的正确属性。
<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!">
<TestTemplate>
<i>
<test:FormItemPlaceHolder ID="ph" runat="server"
Control='<%# Container.Title %>' />
</i>
<br />
<test:FormItemPlaceHolder ID="ph2" runat="server"
Control='<%# Container.Text %>' />
</TestTemplate>
</test:FormItem>
有没有人有更好的解决方案?
答案 1 :(得分:0)
容器不应该定义控件,只能定义数据。
在标记中,您应该定义数据的实际控件,并从容器中为它们分配值。
E.g。
public class TemplateContainer : UserControl
{
public string Text { get { return m_text; } }
public string Title { get { return m_title; } }
private string m_text;
private string m_title;
private FormItem m_item;
public TemplateContainer(FormItem item)
{
m_item = item;
}
}
在标记中:
<test:FormItem ID="fi" runat="server" Title="MyTitle" Text="My Text!">
<TestTemplate>
<i><asp:Label runat="server" Text='<%# Container.Title) %>' /></i>
<br />
<asp:TextBox runat="server" Text='<%# Container.Text %>' />
</TestTemplate>
</test:FormItem>
如果您尝试创建一个不需要在标记中添加控件的复合控件,那么为什么要使用模板?如果只是为了样式,那么创建自己的Style对象可能会更有效吗?