Nested controls in User Control via ParseChildren(false) not worki

K

Karen in England

Hello,

Using ASP.NET 2.0/Visual Studio 2005 Beta 2 and programming in C#, I'm
trying to create a user control that allows nested content between its start
and end tags. From googling around I got the impression that the
ParseChildren(false) attribute was what I needed, so my code looks like this:

[ParseChildren(false)]
public partial class Box : System.Web.UI.UserControl, INamingContainer {
protected override void Render(HtmlTextWriter output) {
// irrelevant code deleted
RenderChildren(output);
// irrelevant code deleted
}
}

I can add this control to a page, and it even does what I want when I test
the page in a browser. The only trouble is, in the Visual Studio designer I
get the error message "Type 'System.Web.UI.UserControl' does not have a
public property named '<name of whatever control I try to use>'". I also
experimented with the PersistChildren attribute to no avail. Am I doing
something wrong, or is this just not supposed to work with user controls?

I tried the same thing with a web control, and it worked just fine in the
designer:

[ToolboxData("<{0}:Box runat=server></{0}:Box>")]
[ParseChildren(false)]
public class Box : WebControl, INamingContainer {
protected override void Render(HtmlTextWriter output) {
// irrelevant code deleted
RenderChildren(output);
// irrelevant code deleted
}
}

Thanks in advance for any responses,
Karen
 
B

Brock Allen

UserControls can't have nested content as defined by the page, since the
ASCX already contains child controls as defined by the ASCX. I think you
just mean a custom control. For custom controls [ParseChildren(false)] tells
the parser that nested content is not meant to be child controls, but to
be property assignments. This is why you get the error. Change it to ParseChildren(true).
The parser will then allow child controls and they will automatically be
added into your control's Controls collection. And then, yes, make sure in
Render() you call base.Render() which will render the child controls.
 
K

Karen in England

Hi Brock,

Thank you very much for your reply. You're correct that I don't have
problems when I write a custom control (subclass of WebControl). I'm just
confused about the following: The name of the argument to the ParseChildren
attribute is "ChildrenAsProperties", so is it possible you're got true and
false backwards in your explanation?

Also, I put together a small test project to test your theory that I
shouldn't be able to get stuff into a user control's control collection by
adding content between its start and end tags. Here's my code (the user
control in this case is completely useless--I was just trying to keep the
example simple):

Test.ascx.cs (The code in Page_Load is just to inspect the contents of the
control collection, whilst the Render method is what's simulating the effect
I want):

using System;
using System.Web.UI;

[ParseChildren(false)]
public partial class Test : System.Web.UI.UserControl, INamingContainer {
protected void Page_Load(object sender, EventArgs e) {
IterateThroughControls(Controls);
}

private void IterateThroughControls(ControlCollection controls) {
foreach (Control control in controls) {
Response.Write(control.GetType().Name + "<br />");
IterateThroughControls(control.Controls);
}
}

protected override void Render(HtmlTextWriter output) {
output.WriteFullBeginTag("table");
output.WriteFullBeginTag("tr");
output.WriteFullBeginTag("td");
RenderChildren(output);
output.WriteEndTag("td");
output.WriteEndTag("tr");
output.WriteEndTag("table");
}
}

Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<%@ Register Src="Test.ascx" TagName="Test" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:Test ID="Test1" runat="server">
<asp:Label ID="Karen" runat="server">Hello World</asp:Label>
</uc1:Test>
</div>
</form>
</body>
</html>

Default.aspx showed up in my browser when I tested as:

LiteralControl
Label
LiteralControl


Hello World


So, it appears that the Label was successfully added to the user control's
control collection. In fact, everything is working as I would have expected
except that I get the error message mentioned in my original post when I try
to view Default.aspx in design mode. What I'm wondering then, is whether
I've left something out that's necessary for designer support, or whether
this is just missing functionality in VS? I am, after all, working with a
beta...

Thanks,
Karen

Brock Allen said:
UserControls can't have nested content as defined by the page, since the
ASCX already contains child controls as defined by the ASCX. I think you
just mean a custom control. For custom controls [ParseChildren(false)] tells
the parser that nested content is not meant to be child controls, but to
be property assignments. This is why you get the error. Change it to ParseChildren(true).
The parser will then allow child controls and they will automatically be
added into your control's Controls collection. And then, yes, make sure in
Render() you call base.Render() which will render the child controls.


Hello,

Using ASP.NET 2.0/Visual Studio 2005 Beta 2 and programming in C#, I'm
trying to create a user control that allows nested content between its
start and end tags. From googling around I got the impression that
the ParseChildren(false) attribute was what I needed, so my code looks
like this:

[ParseChildren(false)]
public partial class Box : System.Web.UI.UserControl, INamingContainer
{
protected override void Render(HtmlTextWriter output) {
// irrelevant code deleted
RenderChildren(output);
// irrelevant code deleted
}
}
I can add this control to a page, and it even does what I want when I
test the page in a browser. The only trouble is, in the Visual Studio
designer I get the error message "Type 'System.Web.UI.UserControl'
does not have a public property named '<name of whatever control I try
to use>'". I also experimented with the PersistChildren attribute to
no avail. Am I doing something wrong, or is this just not supposed to
work with user controls?

I tried the same thing with a web control, and it worked just fine in
the designer:

[ToolboxData("<{0}:Box runat=server></{0}:Box>")]
[ParseChildren(false)]
public class Box : WebControl, INamingContainer {
protected override void Render(HtmlTextWriter output) {
// irrelevant code deleted
RenderChildren(output);
// irrelevant code deleted
}
}
Thanks in advance for any responses,
Karen
 
B

Brock Allen

Thank you very much for your reply. You're correct that I don't have
problems when I write a custom control (subclass of WebControl). I'm
just confused about the following: The name of the argument to the
ParseChildren attribute is "ChildrenAsProperties", so is it possible
you're got true and false backwards in your explanation?

You're absolutely right -- sry about that. I always get it confused with
PersistChildren(false). So yes, it should read ParseChildren(true).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top