And*_*rew 9 asp.net user-controls
我正在创建一个用户控件,我希望它具有内部属性以及普通属性.虽然控件的实际功能与UpdatePanel无关,但我试图创建具有类似ASPX标记的东西.设计页面的开发人员应该能够使用我的控件,如:
<ns:MyControl ID="someID" runat="server" SomeOtherAttribute="true">
<ContentTemplate>
<asp:Label ID="someLabel" runat="server" Text="Normal page markup and controls should go here" /><br />
<p>This should be OK too.</p>
</ContentTemplate>
<ControlEvent ControlName="idOfOtherControl" Event="Click" />
<ControlEvent ControlName="idOfSomeOtherControl" Event="MouseOver" />
</ns:MyControl>
Run Code Online (Sandbox Code Playgroud)
也可以接受将ControlEvent标签包装在其他标签中,更像是使用UpdatePanel时发生的情况:
<ns:MyControl ID="someID" runat="server" SomeOtherAttribute="true">
<ContentTemplate>
<asp:Label ID="someLabel" runat="server" Text="Normal page markup and controls should go here" /><br />
<p>This should be OK too.</p>
</ContentTemplate>
<ControlEvents>
<ns:ControlEvent ControlName="idOfOtherControl" Event="Click" />
<ns:ControlEvent ControlName="idOfSomeOtherControl" Event="MouseOver" />
</ControlEvents>
</ns:MyControl>
Run Code Online (Sandbox Code Playgroud)
但是,ControlEvents标记应该只允许这个特定的标记,而不是正常的服务器标记或任何东西.
我理解如何获取内部ContentTemplate渲染内容(在我看来Page_Init,我使用的ITemplate.InstantiateIn(placeholderControl)方法).那部分工作正常.我遇到麻烦的地方是让ControlEvent部分工作.我可以在代码隐藏中创建内部属性,如:
[TemplateInstance(TemplateInstance.Multiple)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(ControlEvent))]
public List<ControlEvent> ControlEvents { get; set; }
Run Code Online (Sandbox Code Playgroud)
这样做,ASP.NET似乎明白我想要一个ControlEvents标签.但是,我无法识别属性,无论是内部属性还是属性.相反,如果我尝试第一种类型的标记,我会得到一个运行时解析器错误:"属性'ControlEvents'没有名为'ControlName'的属性." 如果我尝试第二种类型的标记,我会NullReferenceException在运行时获得一个解析器错误,并在该<ns:ControlEvent>行生成错误.
我已经在网上查了一下,但是我没有找到一个很好的例子或解释如何完成我想要做的事情ControlEvent或者ControlEvents.我错过了什么?有人能指点我这里的好榜样吗?
谢谢!
编辑:
事实证明,一些问题是由于我如何使用它将控件注册到页面.如果我使用:
<%@ Register Src="~/Controls/MyControl.ascx" TagPrefix="ns" TagName="MyControl" %>
Run Code Online (Sandbox Code Playgroud)
似乎控件本身在标记中被识别,但事实ns:ControlEvent并非如此.如果我改为Register:
<%@ Register Namespace="Namespace.Controls" TagPrefix="ns" Assembly="MyAssembly" %>
Run Code Online (Sandbox Code Playgroud)
它的作用就是理解控件本身(前提runat="server"是它包含在ns:ControlEvent标签中).但是,MyControl的子控件不再被实例化或渲染,并且控件的事件例如Page_Init并且Page_Load没有被触发.
经过多次搞乱后,我发现我似乎需要两个Register指令.这看起来像是一个混乱的"解决方案",它甚至没有解决所有问题,因为(因为)(至少一些)我的控件中的某些标记没有渲染,尽管模板控件(ContentTemplate)似乎再次起作用.
我可以在这里丢失哪些东西会使这个控件使用起来不那么混乱,这会让这个控件实际上正确地渲染一切?
Nar*_*man 10
属性必须作为a Collection而不是a List; [ParseChildren(true)]除此之外,这里要记住的最重要的事情是父控件必须具有为此设置的属性,否则集合将是null.
以下(服务器控件)示例按预期工作:
public class ControlEvent
{
public string ControlName { get; set; }
public string Event { get; set; }
}
[ParseChildren(true)]
public class SampleControl : System.Web.UI.Control, INamingContainer
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(SampleControl))]
public ITemplate ContentTemplate { get; set; }
[MergableProperty(false), PersistenceMode(PersistenceMode.InnerProperty), DefaultValue((string)null)]
public Collection<ControlEvent> ControlEvents { get; set; }
protected override void CreateChildControls()
{
base.CreateChildControls();
if (ContentTemplate != null)
ContentTemplate.InstantiateIn(this);
if (null != ControlEvents)
foreach (ControlEvent e in ControlEvents)
Controls.Add(new Label() { Text = string.Format("ControlName:{0}, Event:{1}", e.ControlName, e.Event) });
}
}
Run Code Online (Sandbox Code Playgroud)
HTH.
| 归档时间: |
|
| 查看次数: |
4531 次 |
| 最近记录: |