I am having an issue with a custom control rendering its contents (child controls) outside of the tag which leads to runtime errors and issues. In an attempt to simplify things as much as I can, I created the control below but it has the very same issue. I have tried inheriting from Control, WebControl and CompositeControl all resulting in with the same problem. Guessing there is something obvious that I am doing wrong... Thanks for any help.
我遇到了自定义控件的问题,该控件在标记之外呈现其内容(子控件),这会导致运行时错误和问题。为了尽可能地简化事情,我在下面创建了控件,但它有同样的问题。我尝试从Control,WebControl和CompositeControl继承所有导致同样的问题。猜测有一些显而易见的事我做错了...感谢您的帮助。
using System;
using System.Web.UI.WebControls;
namespace MyControls
{
public class TestControl : CompositeControl
{
protected override void CreateChildControls()
{
Controls.Clear();
Controls.Add(new Button() { Text = "TestControl!" });
ClearChildViewState();
}
}
}
Adding the control programmatically results in markup outside the forms tag. Adding the control via markup works correct.
以编程方式添加控件会在forms标记之外生成标记。通过标记添加控件是正确的。
protected void Page_Load(object sender, EventArgs e)
{
Controls.Add(new TestControl());
}
...
<body>
<form name="PageForm" method="post" action="default.aspx" id="PageForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTE5MDEwMTE5MWRkg0FopdvLhTPGxHkGm1xCCOVQz6A=" />
</div>
<div>
</div>
</form>
</body>
</html>
<span><input type="submit" name="ctl04$ctl00" value="TestControl!" /></span>
3 个解决方案
#1
Adding the control through the Page.Form property will render the button inside the form.
通过Page.Form属性添加控件将呈现窗体内的按钮。
Page.Form.Controls.Add(new Button() { Text = "TestControl!" });
However, since the button is not contained within a block, such as a <div>, you might have some layout issues with this button. Use ScarletGarden's approach.
但是,由于按钮不包含在块(例如
#2
This has nothing to do with your custom control. Your problem is caused by how you're adding the control to the page.
这与您的自定义控件无关。您的问题是由您将控件添加到页面的方式引起的。
When you call Controls.Add
in your page's Page_Load
method, this is basically shorthand for:
当您在页面的Page_Load方法中调用Controls.Add时,这基本上是简写:
Page.Controls.Add(new TestControl());
ie, You're adding the control at the end of your entire page's control hierarchy. When the page is rendered, your control is rendered after all the others - even after the closing </html>
tag.
即,您在整个页面的控件层次结构中添加控件。呈现页面时,您的控件将在所有其他页面之后呈现 - 即使在结束 标记之后也是如此。
If you want your control to be rendered inside the form then you need to add it to the form's control hierarchy instead:
如果您希望在窗体内呈现控件,则需要将其添加到窗体的控件层次结构中:
Form.Controls.Add(new TestControl());
If you need even more fine-grained positioning, then you need to put a placeholder
(or div
or span
etc) on your page in the required position and add your control to that, as in ScarletGarden's answer.
如果你需要更细粒度的定位,那么你需要在你的页面上放置一个占位符(或div或span等)所需的位置并添加你的控件,如ScarletGarden的答案。
#3
Your control seems ok, I think you have a problem with adding your control to your page,
您的控件似乎没问题,我认为您将控件添加到页面时遇到问题,
Add a placeHolder to your page,
将placeHolder添加到您的页面,
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="placeHolder" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
and then add your composite control to this placeholder's controls collection like that :
然后将复合控件添加到此占位符的控件集合中,如下所示:
TestControl testCtrl = new TestControl();
placeHolder.Controls.Add(testCtrl);
#1
Adding the control through the Page.Form property will render the button inside the form.
通过Page.Form属性添加控件将呈现窗体内的按钮。
Page.Form.Controls.Add(new Button() { Text = "TestControl!" });
However, since the button is not contained within a block, such as a <div>, you might have some layout issues with this button. Use ScarletGarden's approach.
但是,由于按钮不包含在块(例如
#2
This has nothing to do with your custom control. Your problem is caused by how you're adding the control to the page.
这与您的自定义控件无关。您的问题是由您将控件添加到页面的方式引起的。
When you call Controls.Add
in your page's Page_Load
method, this is basically shorthand for:
当您在页面的Page_Load方法中调用Controls.Add时,这基本上是简写:
Page.Controls.Add(new TestControl());
ie, You're adding the control at the end of your entire page's control hierarchy. When the page is rendered, your control is rendered after all the others - even after the closing </html>
tag.
即,您在整个页面的控件层次结构中添加控件。呈现页面时,您的控件将在所有其他页面之后呈现 - 即使在结束 标记之后也是如此。
If you want your control to be rendered inside the form then you need to add it to the form's control hierarchy instead:
如果您希望在窗体内呈现控件,则需要将其添加到窗体的控件层次结构中:
Form.Controls.Add(new TestControl());
If you need even more fine-grained positioning, then you need to put a placeholder
(or div
or span
etc) on your page in the required position and add your control to that, as in ScarletGarden's answer.
如果你需要更细粒度的定位,那么你需要在你的页面上放置一个占位符(或div或span等)所需的位置并添加你的控件,如ScarletGarden的答案。
#3
Your control seems ok, I think you have a problem with adding your control to your page,
您的控件似乎没问题,我认为您将控件添加到页面时遇到问题,
Add a placeHolder to your page,
将placeHolder添加到您的页面,
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="placeHolder" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
and then add your composite control to this placeholder's controls collection like that :
然后将复合控件添加到此占位符的控件集合中,如下所示:
TestControl testCtrl = new TestControl();
placeHolder.Controls.Add(testCtrl);