Dynamically loaded controls in the wizard

I have the following code. I'm trying to create a wizard interface type that dynamically loads custom controls that dynamically loads controls for each step. At each step, there is a button that triggers an event. The parent page is expected to load the next control in the wizard. What happens is the same control is executed twice in a row, forcing me to click the button twice.

I need another set of eyes to look at the code.

public partial class CreateTriviaGame : BasePage
    {
        private TriviaGame _game;
        private int _step = 1;

        protected void Page_PreLoad(object sender, EventArgs e)
        {
            LoadStepControl();
        }

        private void LoadStepControl()
        {           
            BaseTriviaGameControl ctrl = null;
            switch (_step)
            {
                case 1:
                    ctrl = (BaseTriviaGameControl)LoadControl("AddEditGame.ascx");
                    break;
                case 2:
                    ctrl = (BaseTriviaGameControl)LoadControl("CrudQuestions.ascx");
                    ctrl.TriviaGame = _game;
                    break;
                case 3:
                    ctrl = (BaseTriviaGameControl)LoadControl("AddEditPaymentInfo.ascx");
                    ctrl.TriviaGame = _game;
                    break;
                case 4:
                    ctrl = (BaseTriviaGameControl)LoadControl("ConfirmPayment.ascx");
                    ctrl.TriviaGame = _game;
                    break;
                case 5:
                    ctrl = (BaseTriviaGameControl)LoadControl("ThankForPayment.ascx");
                    ctrl.TriviaGame = _game;
                    break;
            }

            ctrl.EntitySaved += new EventHandler(ctrl_EntitySaved);
            holder1.Controls.Add(ctrl);

        }

        protected void ctrl_EntitySaved(object sender, EventArgs e)
        {
            _game = ((BaseTriviaGameControl)sender).TriviaGame;
            _step++;
            holder1.Controls.Clear();
            LoadStepControl();
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            _game = (TriviaGame)ViewState["Game"];
            _step = (int)ViewState["Step"];
        }

        protected override object SaveViewState()
        {
            ViewState["Game"] = _game;
            ViewState["Step"] = _step;
            return base.SaveViewState();        
        } 


    }  

      

** EDIT ** I should add that the reason I am doing this is to not add all the controls declaratively to the page and then handle each one by loading them before they need to be loaded.

+2


source to share


3 answers


Use the Page_Init or Page_PreInit event.



+1


source


This setting is pretty weird.

My first suggestion was to explicitly assign an ID to your control during LoadStepControl () so that no matter what the control is, it has the same ID. This will probably help in losing event handlers. My guess is that in your event handler, when you clear the placeholder and add a new control, it gets a different ID this way than when it is added first in PreLoad (). Thus, the ids do not match between postbacks, so no event handler can be found.



My second suggestion was to reuse your approach and just add all controls to the page statically and just set the visibility to false. If you really have a measurable performance issue, it saves you a lot of hassle and I'm talking too much experience with the code you have there;)

My third suggestion would be to just look at using the ASP.Net Wizard control .

+1


source


I am commenting on your approach on the Womp answer. However, I personally hate it when people try to ignore my approach because they don't see the full context of what I'm trying to do. In this case, I recommend a possible solution to your current approach.

  • Save the step in a session or query string so you can use it during the init methods of the page lifecycle. Until you solve the problem of waiting for loading in the view, you cannot solve the problem with the events that caused the Womp.
  • always add the control to the placeholder for the current stride value on every postback during the OnInit page or PreInit event. Also make sure you redo the event at this time as well. You must do this on every load before the viewstate is loaded. This is required to properly initialize the control in your holder.
  • Increase the step and activate the control swap as you do now in the event handler (which always fires correctly, since you return the control to the page every time before the event lifecycle).

Example. When the page loads for the first time, you will add the AddEditGame.ascx control to the holder and hook up the event during OnInit. When the user calls the message back, you put the AddEditGame.ascx control back into the holder and hook up the event so that the control that raised the event (AddEditGame.ascx) is in the control tree of the event loop. When this event is processed, you can increase the step and activate the swap control by injecting CrudQuestions.ascx into the holder and posting its event. When the user calls the post back, you will put CrudQuestions.ascx in the place holder during init, etc.

The biggest changes are that you don't have to rely on waiting for the video to load to see where you are, and you will properly manage your events by placing the control that triggered the postback on the page before the loop happens events.

I hope this makes sense / helps.

+1


source







All Articles