The original problem is how to make the most maintainable code given that I need to have a menu bar that is very similar but not identical in most WebForms.
At first glance I thought I wanted to make a placeholder in a custom user control, which was placed in a master page, then access the placeholder, putting in the unique content within the WebForm and all is happy and maintainable. After reading through the forms and through trial and error, I realize there are some problems with every solution I have tried:
Putting a placeholder control in a user control makes the placeholder and each of its contents difficult to access in the web form (relying on nested instances of FindControl("ID")), events are difficult to bubble up (I assume I have to do this when the control is created in the code behind where it is referenced) or bind (not successful yet despite referencing: http://msdn.microsoft.com/en-us/library/t4z863dh(vs.71).aspx), and the code is difficult to maintain if I want to move/rename the control.
Nesting controls gives the same problem because I want to use one control - making small modifications on many pages. If I nest then I still have to have cross-control knowledge of each other which is difficult in ASP.NET. Regardless, if I nested user controls then I would also need a unique user control per WebForm right?
Copying and pasting the code to each WebForm while simple is also repetitive and error prone.
Apparently, I shouldn't even try to inherit user controls to make unique children: How (if at all) can you make an ASP.NET UserControl inherit from another UserControl?.
I'm new to ASP.NET. Is there some general strategy I should use to make good maintainable code in this scenario?
You need to use a Master Page, and put your menu in there...
http://msdn.microsoft.com/en-us/library/wtxbf3hh(v=vs.100).aspx
Then, for a data-driven menu, try to use one of the template controls like the Repeater to bind your data.
For example, I have a query that returns Page Name and Link - I bind this to a Repeater control to produce my Menu.
<asp:Repeater runat="server">
<HeaderTemplate><ul></HeaderTemplate>
<ItemTemplate><li><a href='<% Eval("Link") %>'><%# Eval("PageName") %></a></li></ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
Related
I have an ASP.NET page with a Wizard control containing several pages of form fields. The data is collected and inserted to a database from the code behind page. I need to set this form up so you can not only insert, but edit a record as well. Since the form is long and complex, I would rather use the existing one and not make a duplicate one for editing, especially since I want to keep both forms exactly the same and any edits would have to be made to both. But it looks like this is what I need to do if I'm going to databind it. But this would also involve putting the Wizard inside of a FormView, and then I'd have to use FindControl to access any of the fields which would mean altering all my already-existing code (which of course would be time-consuming). So should I manually enter all the values from the code behind instead of databinding it? Which is better, to use a FormView and have duplicate forms (plus have to go in and redo the way I access the fields), or to do everything from the code behind?
I cheat in this circumstance. :)
Create each screen as 2 separate user controls
One for edit, and one for view
Then you get access to all you usual coding
Then embed the controls into the Wizard/FormView
I would suggest you to Go Ahead using FormView, as using DataBind control you have more control the functionality and layout Insert/Edit/View template. Since you have specified that your form is very complex and long, if you control from code behind you have to do lot of work to handle this in code behind and lot code required.
Since I have personal experience to develope very complex form using FormView and it was easy for me bind the Value in directly in formview instead if you assign/Get Values of each conrol in code behind and sometimes you have to hide.
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
The website I'm building contains a large number of views which will be displayed on the same place but hidden or shown according to how the user navigates the menu.
It gets quite messy in visual studios design view when you have a MultiView with 10 different views in it. I've already separated the content of each view in several user controls. But is there an alternative to MultiView?
I generally just use a Panel or Placeholder and toggle visibilities manually. But then I don't use the VS designer either...
Assuming you're using ASP.NET webforms here...
This is another reason to invest in some powerful web controls like the Telerik ASP.NET control suite.
You could use their RadTabStrip control along with the RadMultiPage control.
Example here: http://demos.telerik.com/aspnet-ajax/tabstrip/examples/multipage/loading-external-content/defaultcs.aspx
You can specify a ContentUrl for each RadPageView which allows you to separate each view into separate aspx files.
This simplifies your solution by separating each view into their own page and increases performance as RadPageView content is requested only when viewed initially.
The way that I would do this would be to have a placeholder on the page and dynamically add controls to it as needed.
From what you have said it looks like the user navigates a menu and this decides which view to display in the MultiView control...
I would so something like this
ASPX file:
<asp:PlaceHolder id=phContentContainer" runat="server"></asp:PlaceHolder>
Code Behind
switch (MenuSelection)
{
case "LOGIN" //Display the login control
{
ucLoginUserControlType loginControl = (ucLoginUserControlType)LoadControl("~/UserControls/ucLoginUserControlType.ascx");
phContentContainer.Controls.Add(loginControl);
}
}
Obviously you will want to work the codebehind to be a bit more efficient and cleaner than the above would be with 10 views... but you get the idea.
This keeps your aspx page simple and makes future control additions easier to implement.
Hope this helps, I have typed the code from memory, so some syntax may not be right - if you cant get it going give me a shout and Ill dig out some examples of when I have done this.
Good luck!
I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).
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.