I'm new to creating custom controls, so forgive me if I'm missing something incredibly obvious!
I'm having trouble keeping variables up to date in a composite control I'm writing. It's a simple version of the "Wizard" control, but for v1.1. One control is a simple navigation control with previous/next buttons, and another is a list that updates with each button press. The trouble is, the list always seems to be one step behind.
The navigation control is as follows
The list control is very basic:
Finally, the main component is as follows (simplified):
I left out the "Step" class; it's probably not relevant for now.
The actual usage would be something like this:
I put a text message in the navigation control to see what value the variable "Navigation.CurrentStep" is. It seems to work correctly. However, when I try to use this variable in the section marked in red, it's always one step behind. For example, when the page opens first, the first item in the list is bold, as it should be. Pressing "Next" should move onto the next item on the list, but it doesn't. Pressing it again moves the list onto the second item, but the navigation control has moved onto the third.
I hope that's clear. Thanks in advance...
I'm having trouble keeping variables up to date in a composite control I'm writing. It's a simple version of the "Wizard" control, but for v1.1. One control is a simple navigation control with previous/next buttons, and another is a list that updates with each button press. The trouble is, the list always seems to be one step behind.
The navigation control is as follows
Code:
public class Navigation : System.Web.UI.WebControls.WebControl, INamingContainer
{
public Button btnPrev;
public Button btnNext;
public int CurrentStep
{
get { return (int) ViewState["CurrentStep"]; }
set { ViewState["CurrentStep"] = value; }
}
public int StepCount
{
get { return (int) ViewState["StepCount"]; }
set { ViewState["StepCount"] = value; }
}
public Navigation() : base(HtmlTextWriterTag.Div)
{
if (ViewState["CurrentStep"] == null)
ViewState["CurrentStep"] = 0;
if (ViewState["StepCount"] == null)
ViewState["StepCount"] = 0;
}
protected override void CreateChildControls()
{
Controls.Clear();
btnPrev = new Button();
btnPrev.ID = "Previous";
btnPrev.Click += new EventHandler(this.PrevBtn_Click);
btnPrev.Text = "Prev";
if (CurrentStep <= 0) { CurrentStep=0; btnPrev.Enabled = false; } else btnPrev.Enabled = true;
btnNext = new Button();
btnPrev.ID = "Next";
btnNext.Click += new EventHandler(this.NextBtn_Click);
btnNext.Text = "Next";
if (CurrentStep >= StepCount) { CurrentStep=StepCount; btnNext.Enabled = false; } else btnNext.Enabled = true;
Controls.Add(btnPrev);
Controls.Add(btnNext);
// For debugging only
Controls.Add(new LiteralControl(" CurrentStep: " + CurrentStep.ToString()));
}
// Button Click events
public void PrevBtn_Click(Object sender, EventArgs e)
{
if (CurrentStep > 0)
CurrentStep--;
CreateChildControls();
}
public void NextBtn_Click(Object sender, EventArgs e)
{
if (CurrentStep < StepCount)
CurrentStep++;
CreateChildControls();
}
}
The list control is very basic:
Code:
public class Sidebar : System.Web.UI.WebControls.WebControl, INamingContainer
{
public WizardSidebar() : base(HtmlTextWriterTag.Ol)
{
}
}
Finally, the main component is as follows (simplified):
Code:
[ControlBuilderAttribute(typeof(StepBuilder)),ParseChildren(false)]
public class Wizard : System.Web.UI.WebControls.WebControl, INamingContainer
{
private Navigation myNavigation;
private Sidebar mySidebar;
private Step CurrentStep;
private int StepCount;
// Constructor
public Wizard() : base(HtmlTextWriterTag.Div)
{
}
protected override void CreateChildControls()
{
StepCount = Controls.Count;
string StepTitle = "";
// Create placeholders
PlaceHolder phSidebar = new PlaceHolder(); Controls.Add(phSidebar);
PlaceHolder phNavigation = new PlaceHolder(); Controls.Add(phNavigation);
mySidebar = new Sidebar();
myNavigation=new Navigation();
// Set up Navigation controls
myNavigation.ID="Navigation";
myNavigation.StepCount = StepCount-1;
phNavigation.Controls.Add(myNavigation);
[red]// Set up Sidebar
for (int i=0; i<StepCount; i++)
{
CurrentStep = (Step) Controls[i];
CurrentStep.Visible = false;
mySidebar.Controls.Add (new LiteralControl("<li>"));
if (myNavigation.CurrentStep == i)
mySidebar.Controls.Add (new LiteralControl("<strong>" + CurrentStep.Title + "</strong>"));
else
mySidebar.Controls.Add (new LiteralControl(CurrentStep.Title));
mySidebar.Controls.Add (new LiteralControl("</li>"));
}
phSidebar.Controls.Add(mySidebar);
}[/red]
}
internal class StepBuilder : ControlBuilder
{
public override Type GetChildControlType(string tagName, IDictionary attributes)
{
if (tagName == "Step")
return typeof(Step);
else
return null;
}
public override void AppendLiteralString(string s)
{
}
}
The actual usage would be something like this:
Code:
<BA:Wizard id="ctlWizard" runat="server">
<BA:Step Title="Step 1" runat="server" />
<BA:Step Title="Step 2" runat="server" />
<BA:Step Title="Step 3" runat="server" />
</BA:Wizard>
I put a text message in the navigation control to see what value the variable "Navigation.CurrentStep" is. It seems to work correctly. However, when I try to use this variable in the section marked in red, it's always one step behind. For example, when the page opens first, the first item in the list is bold, as it should be. Pressing "Next" should move onto the next item on the list, but it doesn't. Pressing it again moves the list onto the second item, but the navigation control has moved onto the third.
I hope that's clear. Thanks in advance...