Various asp controls in a ASP.NET page - asp.net

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?

Related

Reusing ASP.NET Controls in Multiple Views

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.

best approach for multiple tabbed gridviews

I'm trying to create multiple gridviews in which all would be loaded at pageload. I have 3 sets of data. When user clicks on a tab then it would show the corresponding gridview.
What is the best approach to this? I'm not good at JavaScript or JQuery.
One way I thought of is using a table and image buttons, where I would put gridview1.visible = false when gridview2 tab is clicked. Is this a good way to do it? or is there another intuitive way to do it?
"Easiest approach to use Ajax Tookit Tab Containers and Tab Panels, Put GridView in the content template of TabPanel.
<ajaxToolkit:TabContainer runat="server"
OnClientActiveTabChanged="ClientFunction"
Height="150px">
<ajaxToolkit:TabPanel runat="server"
HeaderText="Signature and Bio"
<ContentTemplate>
-- Grid View --
</ContentTemplate>
/>
</ajaxToolkit:TabContainer>
Refer :
http://www.asp.net/Ajax/Ajaxcontroltoolkit/samples/Tabs/Tabs.aspx

How can I use the dropdownlist to populate/enter data?

Here's my existing code:
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
DataSourceID="dsEmployees" DataTextField="Last_First"
DataValueField="EmpNum"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
Yonita, you need some more moving parts. You need a datasource to bind to, for instance.
Have a look at the Data Access tutorials on the ASP.NET website:
http://www.asp.net/learn/data-access/
DropDownLists end up being rendered as <select> tags in HTML. These do not allow for data entry of new values. If you're looking for something similar to a ComboBox (a textbox and a listbox combined into the same control) then you'll need to find a third-party javascript implementation that is acceptable to you; there is no control which provides that functionality in HTML or the .net framework.

How to have a link in one placeholder open a ModalPopup in a different placeholder?

I have a page with different placeholders. In one of them, I have a link that I want to open a modal popup in a second placeholder (using the ajaxtoolkit ModalPopupExtender) :
<asp:Content ID="content1" ContentPlaceHolderID="placeholder1" Runat="Server">
<asp:LinkButton ID="link" runat="server" Text="Popup link" />
</asp:Content>
<asp:Content ID="content2" ContentPlaceHolderID="placeholder2" Runat="Server">
<asp:Panel ID="panel" runat="server" Text="Popup content" />
<ajaxToolkit:ModalPopupExtender ID="popup" runat="sever"
TargetControlID="link"
PopupControlID="panel"
/>
</asp:Content>
When doing as above, it fires me an exception, saying that popup cannot find link (which I understand, because they are in two different placeholders).
How can I make this work ? I can think of something find FindControl in the code behind, but I don't really like to use this function, as it is pretty computationally expensive (especially with my nested layout).
One issue is that your TargetControlID and PopupControlIDs are reversed. TargetControlID is the ID of the item that you want to 'Modal Pop', in your case that would be Panel1. The PopupControlID is the ID of the control that would trigger the ModalPopup, in your case that would be "Link"
But you still have a few options if that doesn't work, I have fired a modal located in a different update panel before using the method below. Though not the exact same issue, this workaround may help you (I am assuming you have a script manager on your page).
Create a hidden element in Content2 with ID="hiddenLink"
Set your ModalExtender PopupControlID="hiddenLink"
In the codeBehind for "link" in content1, add an onClick event with the following
ModalPopup1.show()
If you are using updatePanels, this will cause the ModalPopup to display in AJAX fashion without page refresh.But you would still get a full postback worht of data between the client and the server.
Method 2, you could use a javascript function to show to Modal as well. Add a behaviorID="MyModal1" (or whatever you want to call it) to your Modalpopup definition. Then change your link:
<asp:LinkButton ID="link" runat="server" Text="Popup link" OnClientClick="$get('MyModal1').show(); return false;"/>
Note: The return false in the above example prevents the .NET page from performing a postback.

One user control updating another during AJAX Postback?

I developed a user control that displays a list of products and it works pretty good. Then I dropped this user control into another user control that allows the user to pick different criteria and the product UC updates to show those products, all pretty slick and with AJAX via UpdatePanel.
All was working just fine... then another requirement came in. The "search" control needs to be separate from the product control (so they can be positioned separately). Initially, I thought this was no problem as I would give the search control a reference to the product control and then it would talk to it via reference instead of directly inside the control (which has been removed).
And they do talk. But the product control loads, but refuses to display.
I checked and it is being passed via reference and not a copy ( as best I can tell ).
There is an updatepanel in the search control. There is an update panel in the product control. And then for good measure, there is an update panel surrounding them both in the actual search aspx page.
I've tried setting the product control update panel to conditional and then fire the .Update() method manually.
What's the secret here?
TIA!
SOLVED
Thanks to Jamie Ide for the tip to use events.
Search Control and Product control still have internal update panels, and NO LONGER have them on this particular page.
Search Control now raises an event OnSearchResultsUpdated and exposes the found items in properties. The page subscribes to this event and takes the properties and passes them to the product control and triggers triggers a .Refresh() method on the product control which simply calls the .Update() on its internal updatepanel.
The Product control, FYI, accepts products in several different flavors. A list of distinct SKUs, a list of product ids, a named collection in our database and finally a given product category.
Our designers need to be able to create a new page, drop the control onto it and set some properties and voila! New site page. They don't want to require a programmer's involvement. So keeping the controls self contained is a requirement. Fortunately all the changes I made still work completely with the other uses of the product control.
THANKS AGAIN SO MUCH!
I don't think there's really enough information to work with here, but my best guess is that the Product control is not getting data bound. You may try calling myProdcutsCtrl.DataBind() from the search control (or something inside the Product control that cause a DataBind() for instance myProductCtrl.Search(value1, value2, value3).
One other thing you might try is removing the UpdatePanels and seeing if things work. Then add them back in once you get core functionality going.
UPDATE: I've gone ahead and put some example code that works here which I believe accomplishes what you want. What follows are snippets for the sake of saving space, but include all code necessary to make it run. Hopefully this will at least give you something for reference.
Things to try:
EnablePartialRendering="true|false" setting it to false will force the natural postbacks and is good for debugging UpdatePanel problems.
Make sure you are seeing Loading... come up on your screen. (maybe too fast depending on your dev computer)
Page.aspx
<%# Register Src="~/Product.ascx" TagPrefix="uc" TagName="Product" %>
<%# Register Src="~/Search.ascx" TagPrefix="uc" TagName="Search" %>
...
<asp:ScriptManager runat="server" ID="sm" EnablePartialRendering="true" />
Loaded <asp:Label ID="Label1" runat="server"><%= DateTime.Now %></asp:Label>
<asp:UpdateProgress runat="server" ID="progress" DynamicLayout="true">
<ProgressTemplate><b>Loading...</b></ProgressTemplate>
</asp:UpdateProgress>
<uc:Search runat="server" ID="search" ProdcutControlId="product" />
<uc:Product runat="server" ID="product" />
Search.ascx
<asp:UpdatePanel runat="server" ID="searchUpdate" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<p>
<asp:Label runat="server" AssociatedControlID="filter">Less than</asp:Label>
<asp:TextBox runat="server" ID="filter" MaxLength="3" />
<asp:Button runat="server" ID="search" Text="Search" OnClick="SearchClick" />
</p>
</ContentTemplate>
</asp:UpdatePanel>
Search.ascx.cs
public string ProdcutControlId { get; set; }
protected void SearchClick(object sender, EventArgs e)
{
Product c = this.NamingContainer.FindControl(ProdcutControlId) as Product;
if (c != null)
{
c.Search(filter.Text);
}
}
Product.ascx
<asp:UpdatePanel runat="server" ID="productUpdate" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:Label runat="server">Request at <%= DateTime.Now %></asp:Label>
<asp:ListView runat="server" ID="product">
<LayoutTemplate>
<ul>
<li id="itemPlaceHolder" runat="server" />
</ul></LayoutTemplate>
<ItemTemplate>
<li><%# Container.DataItem %></li></ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
Product.ascx.cs
IEnumerable<int> values = Enumerable.Range(0, 25);
public void Search(string val)
{
int limit;
if (int.TryParse(val, out limit))
product.DataSource = values.Where(i => i < limit);
else
product.DataSource = values;
product.DataBind();
productUpdate.Update();
}
Code does NOT represent best practices, just a simple example!
I'm fairly new to AJAX, but I don't think it's a good idea for user controls to have UpdatePanels. I would also advise you not to have the user controls reference each other; they should communicate through events and methods controlled by their container.
I do something similar with two user controls for a master-details display. The master raises an event when an item is selected from a list, the containing page handles the event and calls a method on the details display to display the selected item. If I remember correctly, my first attempt had UpdatePanels in the user controls and I wasn't able to make that work. Having the user controls inside an UpdatePanel on the page works fine.
If I understand you right you have a layout like this:
Outer UpdatePanel
SearchControl
Search UpdatePanel
ProductControl
Product UpdatePanel
Databound Control
Which one of those update panels is actually being called?
I assume that if you check the network traffic with something like Fiddler or Firebug if you're using Firefox, you aren't seeing any HTML for the product update panel coming back?
Have you tried doing something like:
UpdatePanel productUpdate =
Page.FindControl("Product UpdatePanel") as UpdatePanel;
if (null != productUpdate){
productUpdate.Update();
}
By default, if a postback is made from an UpdatePanel, only that control will be updated/re-rendered (this is called partial page-rendering).
To also update/re-render other UpdatePanels, you have to either:
set their UpdateMode property to Always
add the control that makes the postback to their Triggers collection
Check this page in MSDN for details.

Resources