A web app our group has put together uses the ASP.NET Wizard control. Each step in the wizard contains a corresponding custom UserControl.
The trouble is that as you go through the wizard steps, all the UserControls are loaded on each step, rather than just the one used in that step. That doesn't seem right to me.
So...is there anybody here that's done a lot of work with the Wizard control and can give some guidelines on how to use it correctly, and keep it from loading way too much junk with each step?
One thing that could help you a bit is not putting any code in your UserControls's Page_Load function but instead putting that same code in it's Page_PreRender. That's crucial when using a MultiView and probably applies to the wizard as well.
mspmsp has a good recommendation about PreRender, another option that I have noticed used before is to simply move all configuration code inside the control to a ConfigureControl method.
Then when switching views, you can call the ConfigureControl() method to explicitly create/load your control. It has the same purpose, but it helps make the code a bit easier to understand in my opinion.
FYI, (at least part of) the reason it loads all user controls on each step is so that you can access the values entered on other steps. If it didn't load the controls, you couldn't easily make decisions about the current step based on what was entered in a previous step (e.g. filtering a list based on a selection in a previous step).
Related
I have recently been tasked with learning EF 6 and web forms scaffolding for our group. Most everything works perfect for me and even though I was ready to hate it I don't. There are a couple of things that I can not make work the way that I want them to. When I scaffold some CRUD pages it works great, but I want to set some default values on the Insert page. I am able to set values in the constructor or the properties, but they do not go to the insert page until the click event to add the item. I have tried every way I could think to figure out an annotation that would work on my object as well as in the Dynamic control. So far I can not make anything work. I can actually remove the dynamic control and add my own control and add it to the object in the insert method, but that just does not feel right. Is there another way of doing this?
Specifically the things that I am trying to do are to set a default date in some fields based on DateTime values over a 30 day period from creation time. I also have state and county dropdowns that are tied to more than just the object that I am working on. Currently I use EF6 and LINQ in my DAL to just populate the dropdowns with objectdatasources and they work great. I want to hook them as dynamic controls as well. I know I need the [DataType] attribute, but there is no dropdown option to choose from. Also I am not sure how to hook up the dropdowns to have the county fire after the state fires so that the counties will change with each state selection. Is there a tutorial somewhere that would cover these things. I have searched everywhere and can not find any guidance.
Thanks Jimmy
Since no one seems to know the answer I thought I would list the needed things to help you if you are having the same issues. If you need to work with the data inside a Dynamic control you are going to have to do a lot of conversions. You must find the Dynamic control in the container you are using and parse that to a dynamic control and then you need to dig into the control template of that control and find the textbox etc that you need and parse that into the needed control type and grab or set its value. If you are needing to keep your code secure and must pass Fortify or some other static analysis tool you will also have to encode the values because fortify can not see that it came from a control that was encoded. This becomes a pain in the butt and it is much easier just to go ahead and switch to a standard control and manually add that in the insert.
The line of code if you need to know how this would work is something like this.
((TextBox)(DynamicControl)fvName.FindControl("DynamicID").TemplateControl.FindControl("TextBox1")).Text;
I wrote this from hand so it might have something out of place, but this should get you on track.
Jimmy
Right now for my User Controls I right click the control in the Solution Explorer and then choose 'View Code'. Then, in the top right corner where all the class's elements are enumerated in a dropdown box, I choose the grey'd out constructor and this brings me to the auto generated .designer.cs file that I'm looking for.
I feel like this is a really round-about way of doing it and it doesn't sit well with me. Am I supposed to be doing a better job of avoiding editing these files? Are they hard to get to on purpose or did I just clearly miss something simple in Visual Studio?
You should quite simply be able to use the treeview of the Solution Explorer to expand the user control items and see the code-behind and designer files.
This is curious, so I wonder what kind of user control (any particular project type)?
As for avoidance of editing these auto-generated files: yes, you should be weary in doing so, and avoid it wherever possible. Your changes are going to disappear if the code is ever regenerated (not that likely for user controls, I suppose), and the developers of the tool that generated it can't vouch for it working as it should if edited.
There are times when you do want to edit these kinds of files, however. So use your own judgement to evaluate the value of doing so. I find myself dipping into the DBML designer files often enough to delete the default constructor which conflicts with my own in the partial definition, haven't found another way to do what I want. Such is the situation.
Editing autogenerated code is never a good idea. The reason being that the code can be generated at any time and your changes will be lost. If you really, REALLY need to edit the code, you should be doing so using partial classes. But 95% of the time you shouldn't need to edit autogenerated code in the first place. What exactly is it that you're trying to accomplish?
An easy way to do it: Let's say you have a Label control called Label1.
If it is never actually used in your code, place some code that uses it somewhere in one of your methods:
private void Test() {
Label1.Text = null;
}
Now, put your Cursor over the Label1 control and press F12. This will take you to the definition of Label1
Hope that helps!
First of all, I hope I'd get some advice about my practice because based on the very few books I've read, they didn't write much in the aspx page..they just built some controls and used them in the aspx page, so is this approach a good practice ?
here comes my question, I thought using web controls instead of directly writing into .aspx page is better as I could reuse the code, but now I'm creating those controls and I don't think I'll reuse them again or maybe only just one more time.
so do you think it's wise to create a control for the code instead of directly coding in the .aspx page ?
I was also working on a web user control for adding a new item to my db, and then I started planing for the update or edit control..I thought maybe I'd use the same control for both add and edit and start reusing my code, and on my way editing the control to be able to function as both add and edit control, I started with adding properties to the control, then a couple assignments in the Load method, then some checks with if...So I realized maybe a new control would be better!
I don't know, I'm thinking intuitively but I could really use a professional, experienced point of view.
Thanks for your time =)
Sometimes creating a user control, allows you to encapsulate some specific logic and ui elements into a separate class. Even if you are not reusing the control, the final code may be simpler to read and maintain. Take by example a Login control, if you take login related decisions in the user control and make those 'details' hidden in the rest of your code, then the code get simpler and easier to read and mantain!
If you're not going to reuse the code, then you don't want a user control or any other kind of control. Just put the appropriate code and controls onto the page.
If you find later that you do want to reuse it, then you can make a user control out of it.
If you know for sure that you are going to want to use a control (or some slight variation) then creating the user control is a no brainer.
For me, if it occurs to me that I may need similar functionality again in some future project then I will sometimes create a control just because I think it will be useful.
I'm using a Wizard in my ASP.NET page, where in the first step the user chooses from a DropDownList, how many sets of controls will appear in the next wizard step (from 1-5).
For example, in the 2nd step of the wizard there are 3 textboxes. If they choose 2 on the previous screen, there will be 6 as there will be 2 sets of these.
I need to be able to store the contents of all these textboxes in a database (simple part I think, there's 5 columns and all can be null.
The easy way of doing this I think is just creating all of the possible controls (5 sets), and hiding them based on what they choose in the previous screen. Is there a more efficient/easier way?
Thanks
It really depends on your definition of efficient/easier.
A more standard approach would be to use a repeater control to display the correct number of controls based on previous input. However if you have not used a repeater control before there will be a degree of learning involved in displaying your output and retrieving user input during the postback.
You can use the ASP.NET Wizard Control
If you absolutely know that 5 boxes is the max, and it is highly unlikely that there would ever be more than that, using Control.Visible on the server controls and their interface items such as label or what ever else, would work... but...
It's a bit brittle of a solution, though; Requiring you to make manual code changes in a few places if you decide to add more possible boxes.
A dynamic solution would let you set a maximum number of options in config, or just a single place in code. It would probably require you to change your database structure a little bit, but that would likely be better for normalization, anyway. It involves dynamically generating the items in the step of the wizard, too.
(More info on that option can be had if desired!)
I'm creating a multi-part web form in ASP.NET that uses Panels for the different steps, making only the Panel for the current step visible. On Step 1, I have a drop-down list that uses a Javascript function to reconfigure some of the fields in the same Panel via "onchange". Obviously, since the client-side script is only affecting the DOM, when I go to Step 2 and then back up to Step 1, the fields in Step 1 are back to their orignal configuration even though the same drop-down choice is selected.
What is a good method for storing the visual state of the Panels between steps? I considered calling the drop-down's onchange function on page load, but that seemed clunky. Thanks!
--
Thanks for the quick answers - I think I'll try out the Wizard, but the AJAX solution also sounds like fun.
You might consider an ASP.Net Wizard control for this- it will automate a lot of what you're trying to do.
I suggest you to use the MultiView control, which is let's say semantically more appropiate. And then store this data in ViewState. I have written something similar and it rocks.
I think your best bet is to maintain all of your state in one place, or don't maintain any state at all. The main problem you're having is synchronizing your client-side state with your server-side state.
Try showing/hiding your panels with javascript instead of posting back, if possible. If not, use some ajax to update values on the server-side as soon as they are selected, rather than when you click the next/previous button.
Otherwise, you could use something like ASP.Net Ajax Toolkit Tabs to help with transitions.
Hope that helps!