I have a user control which contains a number of child controls. I want to be able to change the layout of the control (i.e. change the markup surrounding the child controls) via a property of the user control, but I don't want to have to duplicate the child controls themselves. This precludes using, say, a MultiView with different versions of the layout in each view, since in that case I'd have to duplicate the controls. I'd also rather use markup than emit the code for the control directly (as you'd do in a server control).
To give a contrived example, say I have a label and a textbox. In one layout, I want the label and textbox to be contained by divs and laid out on top of each other. In an alternate layout, I want them to be contained side by side in a table.
Should I just go ahead and duplicate the controls between each view? It seems like a violation of the DRY principle, but I'm not sure if I have much choice. A partial solution would be making the views of a multiview into naming containers so that I could at least save myself the time of having to prefix the duplicate control IDs with something to make them unique.
Thanks! Please feel free to ask if the above doesn't make sense.
You could use a templated user control to define header and footer templates for each section of the user control. From there you can use CSS and/or public properties on the user control to style the pre-defined (non-templated) components of the control.
It really sounds like maybe you should go ahead and create a server control instead of just a user control. You'd have to create the markup in code, but it would allow you the best flexibility.
An idea is to create a second user control, that is clone with the first on the design file but have the same code file.
FileLayout1.ascx
FileLayout2.ascx
both of this have
CodeFile="FileLayout1.ascs.cs" Inherits="FileLayout1"
FileLayout1.ascs.cs
You can load the 1 or the 2.
The limitations/problems are that both ascx must have the exactly same control names, and you have the same control 2 times (but the code is only one time)
From my point of view the good think is that you free to design the layout as you like on both way.
Related
Sorry in advance if this is not the right place to ask this.
I have a task of making a asp.net site into responsive. The site consists of various ASP.NET controls as well as Telerik ones. The problem is that the designs that i have for the mobile view do not comply with the current structure of site, so in many occasions i have to put the same control twice in the same page, and the hiding/showing depending on the width of the screen.
So i did my research and found that only unique IDs are permitted in same page. Is there any alternative to have the same control twice in same page?
No, there isn't. Controls' IDs must be unique.
Perhaps wrapping them in user control instances and using those a few times over and exposing public properties for what you need is one approach.
Consider using tools like RadPageLayout that help you hide/move unwanted controls/pieces of the page: http://docs.telerik.com/devtools/aspnet-ajax/controls/pagelayout/overview.
Or, create helper methods that get the needed user input/control depending on what is visible or not. These could even be properties in your page that return the currently visible control so you can set properties, data sources, get input, etc. With this you will reference the duplicated controls via this property rather then via their instance ID. Tough to maintain, but without completely redesigning your page and needing duplicates I am not sure there is much else you can do.
I've got a set of ASP.Net pages that display a number of asp:TextBox fields depending on the number of entries in a configuration file. I know that the number of fields won't be going above 10 or so. Given that, should I declare a sufficiently large number of text boxes in markup, or should I dynamically create the textboxes in the code-behind?
There are advantages and disadvantages to each approach, which is why I'm having trouble choosing. The advantage to the dynamic approach is that the application is more flexible - even if the number of fields goes above 10, my application will be able to scale. The disadvantage is that I'm now mixing markup and logic - my application is inserting textboxes and literals (for the labels) into the page. This will make future maintenance harder because not all of the fields are in the .aspx file.
The advantage to declaring a large form and then just showing or hiding the necessary fields is that it keeps logic and markup separate. The disadvantage, of course, is that I lose flexibility. If the number of fields goes beyond the amount I anticipate (and there is a small risk of that) I have to revisit the application to add more fields.
So, StackOverflow, which would you choose? More importantly, why would you choose your approach?
One option is to combine the best of both worlds. If you put your textbox in a repeater, you can then dynamically control how many repeater rows are displayed, while having the controls statically declared.
I would definitely go with the dynamic approach because, as you say, this will scale if requirements change in the future and you will not be sending unnecessary markup to the browser.
I don't see how using static fields avoids the issue of mixing logic and markup as you will need to use code to hide the unwanted controls.
I'm writing an ASP.NET app in which a table of objects is created by the user client-side.
I envisage them clicking "Add item" and a new 'row' is created in the table with textboxes for them to enter their stuff.
I can do this fine by adding HTML with jQuery. The problem is that one of the fields in the row for the user to fill in needs to be a colour picker.
I have an ASP.NET web user control for my colour picker. How do I add an instance of it to the page within my html row? Or am I barking up the wrong tree here - is there a better way of encapsulating the functionality of my colour picker so that it can be put on every row?
No, you can't add a server-side asp.net control to a page that has already been rendered using client-side techniques (aka Javascript)
Two options:
Firstly, switch to using a client-side colour picker. You can then have the data from this included in the post-back by dynamically adding hidden fields to your form.
Secondly, have a single editing panel which includes your colour picker. Users then select a row to edit, which updates the edit panel with current values etc. Values are stored in hidden fields created when you dynamicaly add rows to your table, and included in the post-back
Without seeing your UI, I can't comment as to which would be best. The asp.net control might look nicer, but it might be difficult to work into your design. A pure client-side solution might fit your designer better, but might not look so good. You also need to consider what happens if / when a users adds lots of rows (this might be 10, 50 or 100 depending on your app /code). Lots of dynamically added controls (the first solution) might cripple the performance of the page.
I'm not sure what version of ASP.NET you're using, one approach that would work is to turn your usercontrol into a custom control. You'd then need to implement ICallbackEventHandler (the first way to do Ajax on asp.net); for sure it's a bit more work but it does give you a good level of control.
Alternatively, you could try this
You can't add ASP.NET controls with jQuery (at least not easily). You could, however, perform a postback when you need to add the colour picker to the row.
In the code in front declaratively define a template of what the new row should look like, then hide it using css.
When the user clicks the 'Add new button' select and cloen the contents of your hidden template and write that into your target div. Just make sure to remove the hiding css when you do this.
You will, of course, just be copying the rednered html of your server controls, but htis apporach may give you a quick and easy way of doing what you need
What are some scenarios where MultiView would be a good choice? The MultiView control along with its View controls simply seem to extend the notion of Panels.
Both Panels and MultiViews seem prone to abuse. If your UI concerns and biz logic concerns are properly separated, why lump views together in a single ASPX?
I have used MultiViews as a more flexible basis for a Wizard control.
I do agree that lumping lots of views together is a code smell. In the case of a wizard there are often lots of pieces of state you want to share throughout the process. The multiview allows this state to be simply stored in the viewstate.
Most of the time I make the contents of each view a single user control that it can encapsulate the logic related to that particular step.
I've used it in the passed to implement a simple Ajax-enabled tab interface.
Style a button to look like a tab, then set it's onClick event to switch the active view in an update panel.
Any situation where you find yourself toggling the display of one or more panels is a prime candidate for a MultiView control. A more templated wizard control, or master / detail forms for example.
I agree that they are open for abuse and you should evaluate whether you're better off separating your code into separate pages before using them. I've worked on projects where the previous developer has tried to put too much onto a single page using MultiViews and they are sheer hell to work with.
One thing to be wary of with MultiViews is that unlike panels, any declarative datasource controls contained inside them will always bind, even when the view they are contained in is not active / visible.
Any time that you want to show different content on a page based on some condition. At work I've created a tab control that just uses a MultiView and another simple control I made that looks like tabs. Each tabs puts a link (which is styled) in the other control that is wired up to set the active view to the correct tab.
It can be useful for things like online forms, where you may have one view showing the actual form and another view displayed afterword with the "thank you" text etc.
I've been trimming the UI of our website by doing the following in the onload event of that control:
btnDelete.isVisible = user.IsInRole("can delete");
This has become very tedious because there are so many controls to check again and again. As soon as I get it all working, designers request to change the UI and then it starts all over.
Any suggestions?
One simple suggestion would be to group controls into panels based on access rights
Something I have done before has been to create a custom page class (Actually, I do this part on every project) that each ASP.NET Page inherits.
This page class contains an IsAdmin property.
I then subclass the commonly used controls that may or may not be visible between modes into custom controls, and add code to check the Pages IsAdmin property.
All this is maybe an hour of work, but if you build pages using these controls, they manage their mode automatically.
Another fun timesaving tip is if you need to flip the page in and out of readonly mode. I added a property to the main base class, and then added a custom control that renders a textbox in one mode, and a label in the other.
Again, a little bit of time on the components, but then you can create a readonly version of the page in 2 lines of code...Very worth it.
You may be thinking of the situation in the wrong way. Instead of thinking of individual controls, think of it in terms of business roles and what they have the ability to do. This goes along with grouping controls into panels for access rights. For example, maybe only managers have the ability to delete and do other things, and you have a role for managers that you check. This way if there are changes, you can just move users into different roles. Business rules should not change drastically. There will always be tweaking as new positions gain more responsibility, but thinking of it in this way should minimize the number of changes to be made.
A quick and dirty option is using the asp:loginview controls, which can be wired up to user roles.
Not as elegant as the custom page class option suggested by Jonathan, and can be a bit of a performance hit if they are all over the page.