我正在尝试学习如何使用ITemplate来实现更好的自定义控件。我已经让它大部分工作了,但是我还不能弄清楚如何从页面访问容器的任何属性。
下面是我的模板化控件:
[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{
private ITemplate _CustomPanelContainer;
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(CustomPanelContainer))]
[TemplateInstance(TemplateInstance.Single)]
public virtual ITemplate CustomPanel
{
get { return _CustomPanelContainer; }
set { _CustomPanelContainer = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
if (_CustomPanelContainer != null)
{
var p = new Panel();
p.ID = "CustomPanel";
Controls.Add(p);
_CustomPanelContainer.InstantiateIn(p);
}
base.CreateChildControls();
}
public class CustomPanelContainer : Panel, INamingContainer
{
private string _Test = "TESTING!";
public string TextTest
{
get
{
return _Test;
}
set
{
_Test = value;
}
}
}
}下面是页面实现:
<uc1:Example runat="server" ID="Example1">
<CustomPanel>
<strong>Test: </strong> <%# Container.TextTest %>
</CustomPanel>
</uc1:Example>它在很大程度上是有效的,但问题是<%# Container.TextTest %>总是返回一个空字符串。当我在调试器上运行它时,我在CustomPanelContainer的TextTest属性内的行上放置了一个断点,断点永远不会命中,因此实际上永远不会访问该属性。
这里我漏掉了什么?如何通过<%#Container访问容器的公共属性?
发布于 2021-10-22 17:46:28
我终于想出了如何让它按照我想要的方式运行。
我删除了ITemplate作为容器的类型,将类型设置为实际的类型,并向CreateChildControls()添加了一个DataBind()命令。
也许这不是正确的方法,但它是有效的。
让这个问题开放一段时间,看看是否有人提出了任何批评或更好的方法,因为我真的不知道我在这里做什么。
简化的工作代码:
[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public virtual CustomPanelContainer Template { get; set; }
protected override void CreateChildControls()
{
Controls.Clear();
if (Template != null)
{
Template.DataBind();
Controls.Add(Template);
}
base.CreateChildControls();
}
public class CustomPanelContainer : Panel, INamingContainer
{
public string TextTest
{
get { return "TESTING!"; }
}
}
}页面实现:
<uc1:Example runat="server" ID="Example">
<Template>
<strong>Test: </strong><span><%# Container.TextTest %></span>
</Template>
</uc1:Example>编辑:当需要隐藏模板的类型时,这也是有效的。也就是说,上面的代码公开了模板的类型,以允许操作Panel的属性作为模板的属性,而下面的代码隐藏了模板的类型,以阻止对其属性的操作。
[ParseChildren(true)]
[PersistChildren(false)]
public partial class Example : UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
[TemplateContainer(typeof(CustomPanelContainer))]
public virtual ITemplate Template { get; set; }
protected override void CreateChildControls()
{
Controls.Clear();
if (Template != null)
{
var p = new CustomPanelContainer();
Template.InstantiateIn(p);
p.DataBind();
Controls.Add(p);
}
base.CreateChildControls();
}
public class CustomPanelContainer : Panel, INamingContainer
{
public string TextTest
{
get { return "TESTING!"; }
}
}https://stackoverflow.com/questions/69677598
复制相似问题