Reusing ASP.NET Controls in Multiple Views - asp.net

Is it possible to reuse asp.net controls in multiple views within a MultiView? I would like to provide my customers the option to view and entry form as either a ASP.NET Wizard or as a Form depending on their preference. Most of my research has resulted in numerous hits for MVC, but I'm using WebForms and can't find a definitive answer either way.
My theory is that this should be possible, but since the control is already defined elsewhere on the page, I ought to be able to simple tell it to re-display the same control at a different location.
For Example something like this perhaps:
<asp:MultiView ID="mv" runat="server" ActiveViewIndex="0">
<asp:View ID="WizardView" runat="server">
<asp:Wizard ID="wizzy" runat="server" ActiveStepIndex="0">
<WizardSteps>
<asp:WizardStep ID="WizardStep1" runat="server">
<!-- Wrapped in PlaceHolder goodness :P -->
<asp:PlaceHolder ID="wPH1" runat="server">
<asp:Label ID="MyLabel" runat="server" Text="Hello Stackies"></asp:Label>
</asp:PlaceHolder>
</asp:WizardStep>
</WizardSteps>
</asp:Wizard>
</asp:View>
<asp:View ID="FormView" runat="server">
<form action="#" method="post" id="wizzyform">
<!-- I WANT TO REUSE THIS CONTROL HERE -->
<asp:PlaceHolder ID="fPH1" runat="server"></asp:PlaceHolder>
</form>
</asp:View>
</asp:MultiView>
UPDATE WITH ANSWER!!
I simply added some PlaceHolders to my Markup and created a toggle button in my VB.NET Codebehind with the following.
Protected Sub ToggleView() Handles ViewToggleBtn.Click
If RequestWizard_mv.ActiveViewIndex = 0 Then
ViewToggleBtn.Text = "Toggle Wizard View"
RequestWizard_mv.ActiveViewIndex = 1
fPH1.Controls.Add(wPH1)
ElseIf RequestWizard_mv.ActiveViewIndex = 1 Then
ViewToggleBtn.Text = "Toggle Form View"
RequestWizard_mv.ActiveViewIndex = 0
wPH1.Controls.Add(fPH1)
End If
End Sub
WOOT!! :D SO HAPPY!! You have no idea how much pain this saves me :P
Note: I've noticed it doesn't maintain state very well, but super easy fix compared to re-writing double the code >.<

At least, you can have one instance of Label in your code-behind and add it programmatically to the desired place by condition using placeholders in both places.
Also you can make a new user control, and place all the logic that covers your Label there. You will still have 2 instances of this control, but you will design your Label once.

Related

Why can't controls in Templates be referenced via their parent?

I've been wondering to why you have to use FindControl to reference the checkbox in the Login1's LayoutTemplate. Example:
var login1CheckBox1 = (CheckBox)Login1.FindControl("CheckBox1");
I would expect to be able to do something along the lines of:
var login1CheckBox1 = Login1.LayoutTemplate.CheckBox1;
In the case of the Repeater below, it is obvious, because there can be n number of CheckBoxes.
But for the Login control, it doesn't seem to make sense. Why wouldn't this be implemented differently?
<asp:Login ID="Login1" runat="server">
<LayoutTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</LayoutTemplate>
</asp:Login>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:Repeater>
Does anyone have any light to shine on this?
A control added to a page via markup is defined in the designer partial class, generally, at design time.
A control added to a template is generally instantiated programmatically within the control's collection of controls.
Since the control added to the template does not exist at compile-time in the definition of that control, it would be rather impossible to achieve the syntax you're aiming for.
When creating a page in markup, we're using the IDE's facilities to generate a partial class. When defining a template in markup, we're simply setting the value of the ITemplate for that control.

asp.net: Setting up multiple forms on a page

I have a master page that contains a search box which is validated as a required field before the user can submit the search field.
The problem I'm having now is that one of my content pages has a DetailsView which won't let me edit a record, because the search box coming from the master page is blank.
The structure of the code is like this:
Master Page:
<form runat="server">
<asp:RequiredFieldValidator ID="SearchBoxRequiredFieldValidator"
runat="server" ControlToValidate="searchTextBox"
Display="None" ErrorMessage="Enter an employee's last name"></asp:RequiredFieldValidator>
<asp:TextBox ID="searchTextBox" autocomplete ="off" runat="server" Width="180px"></asp:TextBox>
<asp:Button ID="SearchButton" runat="server" Text="Employee Search"/>
<!--.....-->
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
</form>
The "MainContent" placeholder is populated with a page with only a DetailsView. How should I change my code so that I can submit forms from my MainContent pages, but also allow the Master page's search feature to function properly?
I'm pretty new to asp.net forms, so any help is greatly appreciated!
Take a look at ValidationGroups. You can separate each logical form into different validation groups giving the effect of multiple discrete forms.

Create a web page as 2 parts

I want to develop a registration form with 2 panels. One panel is personal information and another is address details. In these panels the user fills in all details of personal information and after completion of this, the user clicks on Add Address Details. If the user clicks on that, the second panel should be visible without page refresh. How can I accomplish this?
you would use javascript to append the append the second form to to the div of the first form. Or however you have it setup. So in jquery it would look something like this:
<script type="text/javascript">
$('#buttonid').click(function() {
$('#divid').append("<form><input />etc etc etc</form>");
});
</script>
You should use the ASP.NET Wizard control. It is the perfect tool for these scenarios. Scott Gu has a post with some links explaining how to use it. I recommend you look at it.There's a video linked that walks you through a full example.
I don't know, but hiding/showing panels based on certain conditions on the same page feels inelegant and hacky to me.
You should look into using an UpdatePanel. Within there you could place to Panels with different form information. Tie in a few button clicks and hide/show the different panels.
Edit with a simple example
<asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>
<asp:UpdatePanel id="upnl" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:Panel ID="pnl1" runat="server">
<!--personal info-->
<asp:Button ID="btn1" runat="server" Text="this button could validate personal info, hide pnl1 and show pnl2" />
</asp:Panel>
<asp:Panel ID="pn2" runat="server" Visible="false">
<!--address info-->
<asp:Button id="btn2" runat="server" Text="this button could validate address information and finally submit the form." />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>

How to use ClientIDMode in ASP.NET 4

The default value of ClientIDMode for a page is AutoID. The default
value of ClientIDMode for a control is Inherit. If you do not set
ClientIDMode for a page or for any controls on the page, all controls
will use the AutoID algorithm.
This is from msdn. But when I created a web application in ASP.NET 4 or even 3.5, all of the ids of the control are what I have written for them. They are not generated by the autoId algorithm. Then I tried to manually add clientIDMode="AutoID" to the controls, it also doesnt work what I was expected. So what is the problem ? Is there any rule to make it available ?
Thanks in advance,
EDITED
This is in .aspx page
<div>
<asp:Panel ID="Panel1" runat="server">
<asp:Panel ID="Panel2" runat="server">
<asp:Panel ID="Panel3" runat="server">
<asp:Panel ID="Panel4" runat="server">
(:
</asp:Panel>
</asp:Panel>
</asp:Panel>
</asp:Panel>
</div>
This is output:
<div id="Panel1">
<div id="Panel2">
<div id="Panel3">
<div id="Panel4">
(:
</div>
</div>
</div>
</div>
The reason you are getting all your Id's coming out the way you are is because there is no reason for the .NET framework to change them.
If you had placed your Panel's within a Repeater control, then they would all change to avoid multiple ID's of the same name.
Example (not correct markup):
<asp:Repeater id="repeater1" runat="server">
<template>
<asp:Panel id="Panel1" runat="server">
<asp:Panel id="Panel2" runat="server">
</asp:Panel>
</asp:Panel>
</template>
</asp:Repeater>
Your HTML which is generated from this would show that the Panel id's have been changed to inherit from the containing control. Something like repeater1_ct100_Panel1
The same happens when you are using Master Pages, Content Holders, and DataBound Controls. .NET updates the ID's to avoid multiple ID's of the same name.
The differences between the different ClientIDMode values can be clearly seen if you nest one control into another; the AutoId mode names the control after each parent naming container, while the Static mode starts a new naming hierarchy. Predictable mode is mostly used with data binding controls, while Inherit mode causes the control to use its parent's ClientIDMode.

Various asp controls in a ASP.NET page

I am creating a products page, where the user selects an option in a radiobuttonlist for example, and then a control with the various options of that product appears in a placeholder or in a div when on of the radiobuttons is selected.
At the moment this is the code:
aspx:
<form runat="server">
<asp:CheckBoxList ID="Lentes" runat="server" OnClick="EscolheLentes">
<asp:ListItem Value="LU">
Lentes Unifocais
</asp:ListItem>
<asp:ListItem Value="LP">
Lentes Progressivas
</asp:ListItem>
</asp:CheckBoxList>
<asp:PlaceHolder runat="server" ID="PHLentes"></asp:PlaceHolder>
</form>
aspx.vb:
Protected Sub EscolheLentes()
Dim ControlLente As Control
If (Me.Lentes.Items.FindByValue("LU").Selected) Then
ControlLente = LoadControl("LentesUnifocais.ascx")
ElseIf (Me.Lentes.Items.FindByValue("LP").Selected) Then
ControlLente = LoadControl("LentesProgressivas.ascx")
End If
Me.PHLentes.Controls.Add(ControlLente)
End Sub
Need to use some ajax to load the control right?
Am i going in the right direction?
Thanks.
There are several ways to achieve that:
True ASP.Net Web forms: Do postbacks with AutoPostback and play with the visibility of the other controls
Javascript: Load all the data possibly displayed with the page and handle the conditional display with javascript. This is only reasonable if the amount of data to display on one page is somewhat limited. You may want to look into JQuery or something similar if you go that way.
Ajax: load asynchronously only the bits you need. You may use the MSAjax framework, or Jquery (or similar) to do the client side code.
The first option is probably the fastest one to implement.
Have you tried adding AutoPostBack="true" and Visible="true" on your control?

Resources