How to get a composite-control's child controls at design-time - asp.net

I am designing an ASP.NET v3.5 custom control based on CompositeControl.
However, I do NOT want to create my child controls via code, but rather as
embedded HTML tag elements within the CompositeControl in the ASPX page, such as:
<cc:MyCompositeControl ID="MyControl">
<asp:Label>Cat</asp:Label>
<asp:Label>Cat</asp:Label>
</cc:MyCompositeControl>
At run time, MyControl.Controls contains the two labels as expected.
At design time, MyControl.Controls is empty.
I need this information at design time for various reasons.
What am I doing wrong?

You might consider taking a look at the System.Web.UI.WebControls.Panel control in the System.Web DLL using Reflector. That will help you get some idea of what properties and what attribute decorations are necessary to provide the design-time support you need.

Related

Why don't my user controls render?

I've created a set of user controls in vb.net and in their original project they work fine.
I've since created a user control library dll and I wish to use it in a new project.
I add the reference to the dll fine, specify the tag library in an asp.net page fine and define controls on the page fine.
Everything seems to work except I get no rendered output.
Various properies of the controls and the page_load methods are all called.
Asp.net trace shows the controls in the page hierarchy etc
Just no output where the controls should be - any suggestions?
Update 1
I just compared a trace of the working output compared to the non working.
The working output contains the user controls (and all elements in them)
The non working output only lists the user controls - no content
It therefore seems that the content of the controls is missing somehow - as if the markup is not being compiled with the codebehind, only the codebehind seems to be working.
Update 2
The controls are inheriting from UserControl not control.
You are correct in your summarization in Update 1- your markup has not been included!
You need to provide a bit of elbow grease if your trying to distribute .ascx controls in a .dll but not too much thankfully.
The two main things you need to do:
Embedded your .ascx controls. The .ascx controls need to be marked as an embedded resource in your .dll (as oppossed to 'content')
Create a VirtualPathProvider. This will allow you to load the ascx files directly from the dll they are embedded in.
Unfortunately explaining step 2 is slightly lengthy, however this excellent article helped me out in doing exactly what you want to do.
The beauty of distributing .ascx controls like this is that you dont have to tear your hair out writing custom controls (rendering anything over than very simple html is a nightmare to make sense of).
I assume that you are not confusing between user control (.ascx) and custom controls. For user controls to work, one needs both ascx (mark-up file) along with corresponding code-behind class. User control are typically consists of constituent child controls whose hierarchy is specified within ascx file that provides some UI. In a class library (dll) project, you cannot package ascx files - all you get is the code-behind class. Without ascx, the code-behind class will not have any child controls and hence will render empty. In short, you cannot package user controls (ascx) in a class library - you have to add them into your actual web project.
For shared control, one has to use custom controls. Custom controls are code-only and typically provides render override that emits necessary html (or creates the own child control tree dynamically). These controls can be package as a class library and shared across project. Typically, a custom control will also have other helper classes to provide design time assistance (UI Editors etc).

Dynamically creating many instances of ASP.NET usercontrols: How do I create it, and where will my conflicts be?

I haven't seen this implemented before in ASP.NET, but am thinking about a UI that would look and act like this:
Conceptual Overview
A TabControl is loaded and the first tab contains a grid
When a row is double-clicked, a new tab is created with the record detail
The content of the tab/record detail is created by a usercontrol
Many tabs could be created, and therefore many instances of the usercontrol will be created
I know ASP.NET will rename my (runat="server") ID's for me, and that I can use jQuery or ASP.NET server-side code to work with the ID's... My concerns are:
How can I ask ASP.NET to generate a unique ID for each Nth instance of my usercontrol (to be rendered in a placeholder)
How do I actually create that extra instance of the control?
What else do I need to keep in mind?
Since I don't want postbacks I'm considering basing my implementation off of ComponentArt's Callback Control, and using ASP.net usercontrols to achieve this effect. This will allow me to do most things that require a postback, but won't refresh all the elements on a page... just the section that contains the user control. That being said, I'm not tied to a particular implementation.
You should look into the Page.LoadControl method. It works nicely and as far as I remember you put placeholders on your page and load the controls into the PlaceHolders, that's how you control the ids.
One thing that doesn't work out so well with this approach is when your control raises events that your Page object has to handle. If your control is selfcontained however you shouldn't have a problem.
This might help you get started:
http://www.codeproject.com/KB/aspnet/LoadingUSerControl.aspx

ServerControl versus UserControl

I'd like to hear some reasons for using a ServerControl opposed to a UserControl. I've found that I probably overuse UserControls.
My list looks something like this:
Pro UserControl
Easily modified. Need to add a class attribute to an element, hack it out in html.
Quick and easy to create initial view. Everyone can write simple html right?
Pro ServerControl
Performance. No html parsing.
Flexibility. Control rendering down to a gnat's behind.
Reusability. Compile it and stick it in the GAC for later use. Or, sell it.
Anything that I'm missing?
The following two advantages of server controls come to mind:
support for inheritance (because the actual user control at runtime inherits from your code behind, you can't inherit from it anymore)
detailed control over the tag's parsing (should nested tags be treated as child controls or properties, etc.)
support for control adapters (declarative, e.g. in a .browsers file)
support for tag mapping (if you're making your own controls that's often very useful though)
However, user controls do have an additional edge because they're templated:
support for databinding expressions
One other consideration is whether you want visual studio designer support at the time you're building the control or at the time you're using the control on the page. It really irks me that you only get one or the other, but not both.
Performance. No html parsing
I wouldn't expect that to be much of a runtime difference - the .ascx should get compiled on first use as well. Perhaps there's some slight overhead saved by not checking the file for modifications - but I can't think of much else.

In ASP.net is it better to use Server Controls within the ASPX page or create them dynamically in the code behind?

I generally prefer to add controls dynamically, like table and generic html controls, to the ASPX page, rather than add them in the ASPX page and set the properties dynamically.
Which approach is considered "better practice"?
Also is using generic html controls dynamically a better practice than outputting formatted html strings to an asp:literal?
Keep them in the .aspx
Adding them dynamically leads to view state issues and they must be added in each post pack. I ran into this when building a user generated forms app. I Broke down and used the controls visibility property as a work around. That said if your eliminating view state and post back from your app these may not be issues for you.
https://web.archive.org/web/20211031102347/https://aspnet.4guysfromrolla.com/articles/092904-1.aspx
Since in both approaches you end up with a set of code that adds controls and assigns values to their properties then the best practice is the approach that is the most readable.
Due to complex decision logic it may be better to do it all yourself on the hand for fairly static control layout where only the properties need modifying placing the control in the ASPX would be more straight-forward.

asp.net designer how to get the designed page type

I want to find out inside a webcontrol the real type of the page that is designed in Visual Studio 2008.
I can obtain the WebFormsRootDesigner, and somehow i know it is possible to get the
file path of the aspx page.
I would like rather to get the ProjectItem for that page, because it would be an overkill to have the control parse the file, but i cannot find a way to do this.
And from the projectitem of an aspx page i have no clue how to get the page class...
I want my webcontrol to behave differently at designtime depending on the page type.
Thanks
That's a really bad design. It's always bad to have the "inner" behave differently based on the "outer", or the "child" to be based on the "parent".
Instead, have the page tell the control how to behave, by setting a property. Different pages will tell the same control to behave in different ways. This way, if you add a new page, it can still choose to use one of the existing behaviors.

Resources