Creating an ASP.Net Templated Server control - asp.net

I want to be able to do something like this
<test:TabControl id="" runat="server"....>
<ItemTemplate>
<tabItem label="tab1" />
<tabItem label="tab2" />
</ItemTemplate>
</test>
The idea being here is that the only acceptable items in "ItemTemplates" are the tabitem types. There are many asp.net controls that use this, for example the ScriptManager class only allows you to specify certain types of objects under its various collections. Maybe thats the key to this.. I want to add a collection as opposed to a template.
The idea is that in code I will then iterate over each "tabItem" and create the tab as I want it to look (probably rendering div's etc).
Ive had a look at most of MSDN link on how to create templated controls but it doesnt seem to do exactly what I want it to.
Would be grateful for some assistance.

You need either a templated control or a custom control that can parse its content (Read about ParseChildrenAttribute(typeof())). Take a look at this article. Although not exactly your case it can inspire you.

Related

Dynamically change ASP.Net WebForms Control IDs While Maintaining State

We're working with a third party system and we need to modify some ASP.Net controls so that they have a specific token added to their HTML id attribute (so the third party system can identify them from the request), as well as HTML comments before and after the controls' output.
Basically, we need to be able to take say a TextBox (say for "Employee First Name") and dynamically change its output to something like this:
<!-- FIZZBOT_START -->
<input id="EmployeeFirstName_FIZZBOT_" ... />
<!-- FIZZBOT_END -->
We would ideally like to implement this so that the developers only have to do something like this:
<xxx:FizzbotWrapper ID="MyWrapper" runat="server">
<asp:TextBox ID="EmployeeFirstName" runat="server" />
</xxx:FizzbotWrapper>
Is there any way to get such an interface to produce such output, while still being able to:
maintain control state across requests
work properly with Validators
work properly with UpdatePanels
allow developers to refer to the original ID in the codebehind for readability (instead of having to refer to "EmployeeFirstName_FIZZBOT_"
work with out-of-the box ASP.Net controls like TextBox and not just controls we've derived.
I've tried a few ways of doing this (the technique that was the most promising was this, but I ran into some trouble getting it to work with validators, and it wouldn't work at all with controls we don't have the source code to).

client id mode on 2 identical id's

I have an control1.ascx page
and control2.ascx page
both of them have this element:
<asp:TextBox runat="server" ID="txt_name" ClientIDMode="Static"></asp:TextBox>
page.aspx contains both of the controls.
so now the page contains input type text with the id "txt_name" X2.
I am wondering how it is working? can someone explain?
Ideally, you want to use ClientIDMode="Static" only if you are sure that no other control has same name in the page.
For example, you really want to access the ServerControl from external javascript file (althought it is not a good design).
If you are not sure, you want to use Predictable.
As your are using ClientIDMode="Static" thus control's id will be rendered exactly as it is.
ID will be rendered directly. See MSDN docs, this Blog is a good read.
ASP.Net 4+ supports various modes to generate ClientIDs for controls.
Here is a reference for MSDN on ClientID and its' generation modes: http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid(v=vs.100).aspx
To see how ClientID generation works, you may want to refer to this link :
http://www.codeproject.com/Articles/108887/Client-Ids-Generation-with-ASP-NET-4-0
(It has visual explanations on how the ClientID generation works in different cases)
Hope this helps.

Asp.Net page rendering and UI controls modularity

the website I'm currently developing can display dynamically-built forms.
A form is composed of fields, which are created directly by the users and can be displayed as one of multiple types that we support (text box, list box, tickbox, radiobuttonlist etc.). The rendering logic uses a repeater that iterates over a collection of all the fields defined by the user.
Inside the repeater (directly in the aspx page), one instance of each of the types we support is defined.
<asp:Repeater ID="fieldRepeater" runat="server">
<ItemTemplate>
<asp:TextBox ID="textBox" runat="server" />
<asp:DropDownList ID="dropDownList" runat="server" />
<asp:CheckBox ID="checkBox" runat="server" />
<asp:RadioButtonList ID="radioButtonList" runat="server" />
[...]
</ItemTemplate>
</asp:Repeater>
During the loading, we figure out which control is required and actively hide all the other ones.
Being still new to the web based development world, this approach seems very odd to me. My guts would prefer keeping the UI clean and instanciate exactly the controls that are required in CodeBehind and not start "playing" with visibility... but the current approach has some obvious benefits as well.
Is it really how one would do it in a web app?
Are there some best practices here?
Thanks!
I have no idea what the best practice is here, but I have done something similar before in a previous project and tried both approaches. Both will work.
Creating the controls in code-behind can be fiddly, especially if you are having to deal with post-backs. The controls have to be created in OnInit, as otherwise they won't get the posted form values and viewstate populated. This will cause complications if any of the control creation is based on the values of other controls, as you won't known the values without manually delving into the posted form values.
The only practical disadvantage with your current approach that I can think of is that all four controls (TextBox, DropDownList etc.) have to be instantiated and processed server-side by ASP.Net, which is a bit of a waste of resources. But it's probably not too significant; maybe do some profiling to see. I do agree that it seems a bit odd though, it doesn't feel very "clean".
As you said you're new to web development, then I would recommend continuing with your current approach of including all the controls and hiding the irrelevant ones. I just found it simpler when I did, even though it may not seem as nice.
Good luck!

How to construct a control like the Asp.Net ScriptManager

Maybe this is not the best title to it, but this is what I am trying to find out. I need a way to construct a control in ASP.Net that mimics the ScriptManager in that it should look like this:
<uc:MyControl Id="" ...>
<MyListOfItems>
<uc:Item someProperty="value1" someOtherProperty="value2" />
<uc:Item someProperty="value3" someOtherProperty="value4" />
</MyListOfItems>
</uc:MyControl>
How to make the Control have a List of items that you can add items to from the Source of a page.
Thanks in advance for your help.
Basically you need to instruct your control to parse any inner content as subcontrols. This is done using a couple attributes - ParseChildrenAttribute and PersistChildrenAttribute (if you want child controls to be maintained in ViewState).
Create a custom control that inherits from WebControl.
Add a [ParseChildren(true, "MyListOfItems")] attribute to your class.
Create a MyListOfItems property.

Best way to custom edit records in ASP.NET?

I'm coming from a Rails background and doing some work on a ASP.NET project (not ASP MVC). Newbie question: what's the easiest way to make a custom editor for a table of records?
For example: I have a bunch of data rows and want to change the "category" field on each -- maybe a dropdown, maybe a link, maybe the user types it in.
In Rails, I'd iterate over the rows to build a table, and would have a form for each row. The form would have an input box or dropdown, and submit the data to a controller like "/item/edit/15?category=foo" where 15 was the itemID and the new category was "foo".
I'm new to the ASP.NET model and am not sure of the "right" way to do this -- just the simplest way to get back the new data & save it off. Would I make a custom control and append it to each row? Any help appreciated.
You can REALLY cheat nowadays and take a peek at the new Dynamic Data that comes with .NET 3.5 SP1. Scott Guthrie has a blog entry demoing on how quick and easy it'll flow for you here:
http://weblogs.asp.net/scottgu/archive/2007/12/14/new-asp-net-dynamic-data-support.aspx
Without getting THAT cutting edge, I'd use the XSD generator to generate a strongly typed DataSet that coincides with the table in question. This will also generate the TableAdapter you can use to do all your CRUD statements.
From there, bind it to a DataGrid and leverage all the standard templates/events involved with that, such as EditIndex, SelectedIndex, RowEditing, RowUpdated, etc.
I've been doing this since the early 1.0 days of .NET and this kind of functionality has only gotten more and more streamlined with every update of the Framework.
EDIT: I want to give a quick nod to the Matt Berseth blog as well. I've been following a lot of his stuff for a while now and it is great!
There are a few controls that will do this for you, with varying levels of complexity depending on their relative flexibility.
The traditional way to do this would be the DataGrid control, which gives you a table layout. If you want something with more flexibility in appearance, the DataList and ListView controls also have built-in support for editing, inserting or deleting fields as well.
Check out Matt Berseth's blog for some excellent examples of asp.net controls in action.
Thanks for the answers guys. It looks like customizing the DataGrid is the way to go. For any ASP.NET newbies, here's what I'm doing
<asp:DataGrid ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="RuleID" Visible="False" HeaderText="RuleID"></asp:BoundColumn>
<asp:TemplateColumn HeaderText="Category">
<ItemTemplate>
<!-- in case we want to display an image -->
<asp:Literal ID="litImage" runat="server">
</asp:Literal>
<asp:DropDownList ID="categoryListDropdown" runat="server"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
This creates a datagrid. We can then bind it to a data source (DataTable in my case) and use things like
foreach (DataGridItem item in this.GridView1.Items)
{
DropDownList categoryListDropdown = ((DropDownList)item.FindControl("categoryListDropdown"));
categoryListDropdown.Items.AddRange(listItems.ToArray());
}
to populate the intial dropdown in the data grid. You can also access item.Cells[0].text to get the RuleID in this case.
Notes for myself: The ASP.NET model does everything in the codebehind file. At a high level you can always iterate through GridView1.Items to get each row, and item.findControl("ControlID") to query the value stored at each item, such as after pressing an "Update" button.

Resources