I am using the asp.net Ajax Control Toolkit accordion (http://www.asp.net/ajaxlibrary/act_Accordion.ashx) and each accordion pane contains quite a lof information.
All that info is generated in the page but it is not shown because the toolkit gives the non active panes a
(style="display:none;)
But because the info is in the page, it becomes a very heavy page to load.
I am looking for a way to load the panes on-demand: so only if the user clicks the pane an ajax request is send and the pane is loaded and expanded.
Can this be done with this control or should i choose a different accordion? Any help or suggestions appreciated.
update
Currently the Accordion is created with two, nested, repeaters. The first repeater loops over the categories and creates a panel for each category. The second repeater repeates inside each panel takes the content for one category and creates the content of the panel.
Pleun
I don't have the points to comment and ask you questions. Sorry. :(
My questions are in regard to how you plan to create and populate the Accordion.
Will you create panes by hand using markup in the IDE or will you bind the Accordion to a DataSource that will dynamically create the panes you need?
Will you have 3 separate DataSources or a different combination of the following:
1.) DataSource to initialize the number of panels and populate only the panel's Header information.
2.) DataSource to populate the Static Content of all panels on first load.
3.) DataSource to populate the Lazy-Loaded Content of a single panel the user clicks to expand.
With your answers I hope to update this answer with a real one. Thanks.
Update: This is achievable with the Ajax Control Toolkit's Accordion.
I have some very basic code below as proof of concept. It could be smoother, but I'll leave it up to you to add a "Loading" image using the UpdatingProgress control if you find it necessary.
The Accordion in the Aspx markup:
(Notice the UpdatePanels - you can replace them with callbacks if you want, I just wanted to keep the answer simple)
<asp:Accordion ID="acc_Accordion" runat="server" RequireOpenedPane="false"
SelectedIndex="-1" onitemcommand="acc_Accordion_ItemCommand" >
<HeaderTemplate>
<asp:UpdatePanel ID="up_UpdateHeader" runat="server">
<ContentTemplate>
<%--When using "Eval" inside strings for Asp.net controls,
you MUST wrap them in apostrophes ('),
otherwise with (") you will get parser errors!--%>
<asp:LinkButton ID="btn_Header" runat="server"
Text='<%# Eval("HeaderText") %>'
CommandName="UpdatePane" CommandArgument='<%# Eval("ItemID") %>'
Font-Underline="false" ForeColor="Black"
style="width:100%; height:100%; cursor:pointer;"/>
<%--Use Cursor:Pointer to keep a consistent
interface after disabling the button.--%>
</ContentTemplate>
</asp:UpdatePanel>
</HeaderTemplate>
<ContentTemplate>
<asp:UpdatePanel ID="up_UpdateContent" runat="server"
UpdateMode="Conditional">
<ContentTemplate>
<%# Eval("ContentText")%>
<asp:Label ID="lbl_Content" runat="server"
Text="<%# DateTime.Now.ToLongTimeString() %>"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</asp:Accordion>
The Page_Load() - Prep our "dummy" data:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
DataTable dt = new DataTable();
dt.Columns.Add("ItemID");
dt.Columns.Add("HeaderText");
dt.Columns.Add("ContentText");
dt.Rows.Add(new object[] { 123456, "Header 1", "Content A." });
dt.Rows.Add(new object[] { 654321, "Header 2", "Content B." });
acc_Accordion.DataSource = new System.Data.DataTableReader(dt);
acc_Accordion.DataBind();
}
}
The ItemCommand() - This captures button-clicks inside the Accordion:
protected void acc_Accordion_ItemCommand(object sender, CommandEventArgs e)
{
if (e.CommandName == "UpdatePane")
{
AjaxControlToolkit.AccordionContentPanel acp
= (e as AjaxControlToolkit.AccordionCommandEventArgs).Container;
UpdatePanel upHeader
= acc_Accordion.Panes[acp.DisplayIndex].HeaderContainer
.Controls.OfType<Control>()
.Single(c => c is UpdatePanel) as UpdatePanel;
LinkButton btn
= upHeader.ContentTemplateContainer
.Controls.OfType<Control>()
.Single(b => b is LinkButton) as LinkButton;
UpdatePanel upContent
= acc_Accordion.Panes[acp.DisplayIndex].ContentContainer
.Controls.OfType<Control>()
.Single(c => c is UpdatePanel) as UpdatePanel;
Label lbl
= upContent.ContentTemplateContainer
.Controls.OfType<Control>()
.Single(c => c is Label) as Label;
lbl.Text = " ID: " + e.CommandArgument
+ " and Time: " + DateTime.Now.ToLongTimeString();
//You can use the ID from e.CommandArgument to query the database
// for data to update your Repeaters with.
btn.Enabled = false;//Disabling the button for our Header
// will prevent Asyncronous Postbacks to update the content again.
//Only disable this if you don't need to update the content
// when the user clicks to view the pane again.
upContent.Update();//Set UpdateMode="Conditional".
}
}
I know this looks like a lot, but it's only a few lines of code (before wrapping and commenting).
Tip 4 in 6 Tips for Working with the ASP.NET AJAX Accordion Control explains how to determine when the selected index has changed. From the JavaScript event handler you can do whatever you want to update the content of the newly-selected accordion pane (call a web service, use an update panel, etc.)
Combining this with another article explaining how to use an update panel to refesh content when a tab page is selected for a simple demo:
<ajaxToolKit:Accordion ID="accSample" runat="server"
RequireOpenedPane="false" SelectedIndex="-1">
<Panes>
<ajaxToolKit:AccordionPane runat="server">
<Header>Sample</Header>
<Content>
<asp:Button ID="btnSample" runat="server" OnClick="OnShowSample" Style="display: none" />
<script type="text/javascript">
Sys.Application.add_load(function (sender, args) {
if (!args.get_isPartialLoad()) {
var accSample = $find('<%= accSample.ClientID %>_AccordionExtender');
accSample.add_selectedIndexChanged(function (sender, eventArgs) {
$get('<%= btnSample.ClientID %>').click();
});
}
});
</script>
<asp:UpdatePanel ID="upSample" runat="server">
<ContentTemplate>
<asp:DataGrid ID="dgSample" runat="server" Visible="false"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSample" />
</Triggers>
</asp:UpdatePanel>
</Content>
</ajaxToolKit:AccordionPane>
</Panes>
</ajaxToolKit:Accordion>
then in code-behind
protected void OnShowSample(object sender, EventArgs e)
{
dgSample.DataSource = new string[] { "test" };
dgSample.DataBind();
dgSample.Visible = true;
}
Take a look at the ASPxNavBar control (a part of the free ASPxperience Suite) from DevExpress. If the ASPxNavBar’s EnableCallBacks property is set to true, contents of collapsed groups are not represented on the client side. When a group is expanded for the first time, its content is retrieved from the server and then cached on the client. The next time the group is expanded, its content is taken from the client and no callback to the server is performed.
Review the ASPxNavBar - Callbacks (AJAX) Online Demo for more information.
All I can suggest to you is add linkButtons to your headers and panels to your panes:
<Panes>
<asp:AccordionPane ID="First" runat="server">
<Header>
<asp:LinkButton CommandName="ASD2" ID="LinkButton2" runat="server">LinkButton</asp:LinkButton>
</Header>
<Content>
<asp:Panel ID="Panel2" runat="server" Visible="true">
First
</asp:Panel>
</Content>
</asp:AccordionPane>
<asp:AccordionPane ID="Second" runat="server">
<Header>
<asp:LinkButton CommandName="ASD" ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</Header>
<Content>
<asp:Panel ID="Panel1" runat="server" Visible="false">
Second
</asp:Panel>
</Content>
</asp:AccordionPane>
</Panes>
and in the Accordion1_ItemCommand set the Visible property of corresponding panel.
protected void Accordion1_ItemCommand(object sender, CommandEventArgs e)
Related
See below image first.
we have one sidebar navigation(ajax accordion control asp.net)
now when ever user click on link inside side bar related page(content) should display in Content goes here region.
As per given instruction entire page should not be refreshed or in other word in Back Button should not work(In Internet Explorer).
what should be the way to achieve this functionality?
what should be the best suggestion for that?
EDIT: navigation tree is inside MasterPage and Content goes region is in side content page of master page
please suggest me.....
thank you so much....
The Easiest way is to Wrap your side navigation & the Content placeholder in an UpdatePanel. Set the TreeView in the side bar as the UpdateTrigger for the update Panel. But, this approach is a little inefficient.
A slightly better way is ti just wrap the Content Placeholder in an Update Panel, along with a HiddenField in it. Upon a selection in the sidebar, update the HiddenField Value with JavaScript and then refresh the update Panel.
According to:
As per given instruction entire page should not be refreshed or in other word in Back Button should not work(In Internet Explorer).
And
sidebar tree view is in master page and Content goes here region is content page
If my understanding is correct, I think you do not need to place your TreeView control in your master page because you only want one page loading dynamically the content based on the selection of your tree view. So...Why is this important? Well if you place your tree view in your page you can use an UpdatePanel to avoid full posts.
Output of the following code
The following code covers the next points:
A TreeView control is embedded in a UserControl and placed in an ASPX page (left side)
The menu contorl exposes an event that is raised whenever the selected node changes, this event is handled in the ASPX page to dynamically load user controls depending on the user selection on the right side of the page, only one content is loaded at a time.
The controls are embedded in an UpdatePanel therefore you won't change your page and your back button in your browser won't be affected
Note: the user controls keep their state across post backs
(I'm not sure if this is the best way to do it, perhaps you could try to find a solution using only ajax, and avoid the use of the evil updata panels, but certainly this is a way to do it)
I'll try to simplify the code to reduce the size of the post, I will just post the code of one user control, the other one is exactly the same I just changed its title to difference them on the page
ASCX Menu
<asp:TreeView ID="TreeView1" runat="server" onselectednodechanged="Unnamed2_SelectedNodeChanged">
<Nodes>
<asp:TreeNode Text="link1" />
<asp:TreeNode Text="link2" />
</Nodes>
<SelectedNodeStyle Font-Bold="True" Font-Italic="True" />
</asp:TreeView>
ASCX Menu code behind
public event Action<string> MenuChanged = delegate { };
protected void Unnamed2_SelectedNodeChanged(object sender, EventArgs e)
{
this.MenuChanged(this.TreeView1.SelectedNode.Text);
}
ASPX
<asp:ScriptManager runat="server" ID="sm" />
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:HiddenField runat="server" ID="currentControl" />
<table border="0" cellpadding="0" cellspacing="0" width="90%" align="center">
<tr>
<td style="width:50%; background-color: Silver">
<menu:TreeViewMenu runat="server" ID="myTreeViewMenu" OnMenuChanged="myTreeViewMenu_MenuChanged" />
</td>
<td style="width:50%; background-color: Aqua">
<p>Result:</p>
<asp:Panel runat="server" ID="myPanel">
</asp:Panel>
<asp:Label ID="lblMessage" runat="server" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
ASPX code behind
protected void Page_Init(object sender, EventArgs e)
{
if (this.IsPostBack)
{
var cc = this.Request.Form["currentControl"];
if (!string.IsNullOrWhiteSpace(cc))
{
var uc = this.LoadControl(this.Server.HtmlDecode(cc));
this.myPanel.Controls.Add(uc);
}
}
}
protected void myTreeViewMenu_MenuChanged(string e)
{
this.myPanel.Controls.Clear();
switch (e)
{
case "link1":
var cc1 = "~/Content1.ascx";
this.currentControl.Value = this.Server.HtmlEncode(cc1);
var uc1 = this.LoadControl(cc1);
this.myPanel.Controls.Add(uc1);
this.lblMessage.Text = "Updated from: link1";
break;
case "link2":
var cc2 = "~/Content2.ascx";
this.currentControl.Value = this.Server.HtmlEncode(cc2);
var uc2 = this.LoadControl(cc2);
this.myPanel.Controls.Add(uc2);
this.lblMessage.Text = "Updated from: link2";
break;
default:
this.lblMessage.Text = "Updated from default: " + e;
break;
}
}
ASCX
<h1>Content 1</h1>
<asp:TextBox runat="server" ID="txt" />
<asp:Button Text="Process data..." runat="server" OnClick="button_Click" />
<asp:Button Text="Just post" runat="server" />
<asp:Label ID="lblMessage" runat="server" />
ASCX Code Behind
protected void button_Click(object sender, EventArgs e)
{
this.lblMessage.Text = this.txt.Text;
}
You can simply copy-paste this code to test it yourself, this should work
Jupaol's answer works fine but 1 thing need to mention, I came across the problem after implemented Jupaol's idea, the first time I called the user control immediately after I click menu, the button with in the ascx works fine, but if I switch to 2nd one, first click of the button on the 2nd control will not fire on first click, this is because we do not have a "static" ID of the control. It took me almost 3 days to finally figure out why this is happening. so here's part of my code to make. I'm leaving this message in hope that anyone who read this afterwards will make the use of it.
if (!string.IsNullOrEmpty(controlPath))
{
PlaceHolder1.Controls.Clear();
UserControl uc = (UserControl)LoadControl(controlPath);
/**note below LastLoadedControl is anything that could
* be unique to the called control so every time when call back
* it will not confuse the back end so the first fire of eg. a button
* on that loaded control will work
*/
uc.ID = LastLoadedControl;
PlaceHolder1.Controls.Add(uc);
}
I'll also need to thank Jupaol's great contribution so that I can get my site running.
I want to set the textbox contol located in the panel control via code
I know to retrieve the inputted value in the textbox control:
string myVal = Request.Form["txtResult"];
I want to set the txtResult.text = "some text";
makeup snippet:
<asp:Panel ID="Panel1" runat="server" Style="display: none" Width="233px">
<asp:TextBox ID="txtResult" runat="server" AutoPostBack="True"></asp:TextBox>
<br />
<div align="center">
<asp:Button ID="OkButton" runat="server" Text="OK" />
<asp:Button ID="CancelButton" runat="server" Text="Cancel" />
</div>
</asp:Panel>
txtResult is not available within code, I tried to see if it is available in the page_load, it's not
texReults was a typo, its txtResult, I updated the ID
the intellisense does not recognize any cntr by the name txtResult
its a new web application and the panel visibility=True
maybee this wil help, above the snipet, I use ScriptManager from the AJAX Exstension
I am aware of he Asnchronius affects, partial potback, etc.
It's a managed control, you should be able to set it on the Page_Load event:
protected void Page_Load(object sender, System.EventArgs e)
{
txtResult.Text = "some text";
}
Update: Based on your update, there are a couple of things that you would need to check:
Spelling: Are you sure you're spelling the control name correctly?
Its ID in your code is "txtResults", but you're referencing it as
"txtResult".
Designer: Did you copy the aspx page or bypass VS in some way for this page? If so check the .designer file for the reference to the control: i.e. "Page1.aspx.designer.cs"
Visibility: Is the Panel control's visibility set to true? If not, then it won't render the controls that are contained within it.
Update 2: If you're doing this through scriptmanager, then I highly recommend that you read through this: http://www.wrox.com/WileyCDA/Section/Using-the-ASP-NET-AJAX-ScriptManager.id-305492.html
I'm stumped on this one and hope someone out there's done something similar.
I have an ASP.NET application that has a number of AJAX toolkit tabs. The number of tabs varies page to page, since they're dynamically generated based on settings in a config file.
That being said, some of the tabs are database-driven. The load time when a number of these tabs are on the page can be significant, so I want to implement lazy loading.
I'm following Matt Berseth's pattern, but it seems to break down when the number of tabs is dynamic (each tab needs its own method on the page).
If anyone has a suggestion on how to tackle this, it'd be much appreciated.
I've started working with a small app to get the lazy loading to work. This lazy loads the second tab (which is hard coded), but the third tab is what I'm struggling with (it's dynamically added).
Edited to add code: ASPX page
<script language="javascript" type="text/javascript">
function clientActiveTabChanged(sender, args) {
// see if the table elements for the grids exist yet
var isTab2Loaded = $get('<%= this.lbl2.ClientID %>');
// if the tab does not exist and it is the active tab,
// trigger the async-postback
if (!isTab2Loaded && sender.get_activeTabIndex() == 1) {
// load tab1
__doPostBack('btnTrigger', '');
}
// else if (!isTab2Loaded && sender.get_activeTabIndex() == 2)
// load tab2
// __doPostBack('btnEmployeesTrigger', '');
}
</script>
<asp:scriptmanager ID="Scriptmanager1" runat="server"></asp:scriptmanager>
<div>
<cc1:TabContainer ID="tc1" runat="server" OnClientActiveTabChanged="clientActiveTabChanged">
<cc1:TabPanel TabIndex="0" runat="server" HeaderText="Tab1" ID="Tab1">
<ContentTemplate>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Label ID="lbl1" text="I am here" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel runat="server" HeaderText="Tab2" ID="Tab2">
<ContentTemplate>
<asp:UpdatePanel ID="up2" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Label ID="lbl2" Text="Load when called" Visible="false" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnTrigger" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</cc1:TabPanel>
</cc1:TabContainer>
</div>
<input ID="btnTrigger" style="display:none;" runat="server" type="button" onserverclick="btnTrigger_Click" />
<input id="btnTrigger2" style="display:none;" runat="server" type="button" onserverclick="btnTrigger2_Click" />
Codebehind:
protected void Page_Init(object sender, EventArgs e)
{
//TabPanel tp = new TabPanel();
//tp.Controls.Add(new LiteralControl("Load first"));
//tp.HeaderText = "Tab1";
//tc1.Tabs.Add(tp);
//tc1.ActiveTabIndex = 0;
//TabPanel tp2 = new TabPanel();
//UpdatePanel up1 = new UpdatePanel();
//up1.Controls.Add(new LiteralControl("Load me when called"));
////up1.Triggers.Add(new AsyncPostBackTrigger());
//AsyncPostBackTrigger trg = new AsyncPostBackTrigger();
//tp2.Controls.Add(up1);
//tp2.Controls.Add(new LiteralControl("Load when called"));
//tp2.HeaderText = "Tab2";
//tc1.Tabs.Add(tp2);
TabPanel tp3 = new TabPanel();
tp3.HeaderText = "Tab3";
UpdatePanel up3 = new UpdatePanel();
LiteralControl lc = new LiteralControl("Load me when needed");
lc.ID = "lit3";
lc.Visible = false;
up3.ContentTemplateContainer.Controls.Add(lc);
tp3.Controls.Add(up3);
tc1.Controls.Add(tp3);
}
protected void btnTrigger_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2500);
this.lbl2.Visible = true;
}
Is the content of the Tabs also database-driven like a CMS?
You could use UserControls as Content and let all implement the same interface f.e. IDataBindable with a function BindData. On this way you can lazyload these UserControl independently of its content.
On ActiveTabChanged you only have to call this function and thenUpdate on the TabContainer's UpdatePanel.
The quick way to do this might be to not load any tabs (i.e. don't actually give them any content) besides the default until that tab is clicked (detected during OnActiveTabChanged or OnClientActiveTabChanged).
However, Tim's method allows the OnActiveTabChanged method to be as simple as databinding the UserControl relative to that tab - that's probably the best method, though it is more effort.
I have an ASP.Net UpdatePanel that updates on a timer. Within the UpdatePanel and nested in a GridView, I have a TextBox that the user enters a value in with a submit button. Everything works fine, except if the user does not submit the value before the timed interval, the text is removed from the TextBox.
Is there a way to persist the user entry into the TextBox between updates? Is there a better way of doing this?
All suggestions welcome.
Respectfully,
Ray K. Ragan
Code Postscript:
aspx:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = null;
}
</script>
<asp:Timer ID="Timer1" runat="server" Interval="900" OnTick="Timer1_Tick"></asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:DataList RepeatColumns="5" RepeatDirection="Horizontal" ID="dlMine" runat="server" OnItemCommand="Item_Command">
<ItemTemplate>
<div style="border:1px solid black;margin:3px;height:300px;text-align:center;padding:5px;">
<div style="width:150px;">
<asp:Label ID="lblTitle" runat="server" Text='<%# left(DataBinder.Eval(Container.DataItem,"title").ToString(), 75) %>'></asp:Label>
</div>
<asp:Label ID="Label1" runat="server" Text='<%# (DateTime)DataBinder.Eval(Container.DataItem,"end_date") %>'></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text='<%# String.Format("{0:C}",DataBinder.Eval(Container.DataItem,"current_value")) %>'></asp:Label>
<br />
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Button Visible='<%# (isInThePast((DateTime)DataBinder.Eval(Container.DataItem,"end_date"))) ? false : true %>' CssClass="bid_button" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Revalue" ID="btnBid" Text="Submit New Valuation" />
</div>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Tick += new EventHandler<EventArgs>(Timer1_Tick);
if (!IsPostBack)
{
dataBindList();
}
}
protected void dataBindList()
{
if (Request.QueryString["GroupID"] != null)//Are they coming here with a URL var? If so, build content object
{
List<Item> itemList = ItemManager.getItemsByGroupID(Request.QueryString["GroupID"].ToString());
dlMine.DataSource = itemList.Take(15);
dlMine.DataBind();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
dataBindList();
UpdatePanel1.Update();
}
protected void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "Revalue")
{
Person p = (Person)Session["Person"];
foreach (DataListItem item in dlMine.Items)
{
string textBoxText = ((TextBox)item.FindControl("txtNewValue")).Text;
Utilities.writeLog("txtNewValue: " + textBoxText, 1);
}
dataBindList();
UpdatePanel1.Update();
}
}
You're rebinding the DataList every time the Timer ticks. All changes in the ItemTemplates of the DataList will be lost on postback.
Why not use Javascript to "pause" the timer whenver one of the textboxes gains focus. This will prevent the Timer from firing and let users finish entering text. Once they leave the textbox of "onblur" then you can restart the timer.
Update
The following will take a bit of effort to make it happen but you can do something like:
When the Timer posts back, before rebinding, iterate over the DataList while searching for textboxes with text in them. Something like:
foreach (DataListItem item in dlMine.Items)
{
//find the textbox control and check for text
}
At this point, you'll know which rows need there textboxes repopulated. Store this information in a hashtable.
In the DataList ItemDataBound event, check each rowID against the hashtable to see if its corresponding textbox exists. If so, repopulate the textbox in the DataList row.
Are you initializing the TextBbox value in your code-behind, perhaps in Page_Load or another page method?
TextBox1.Text = "";
If so, that code is executing on every timer event. You can prevent that like this:
if (! IsPostback) {
TextBox1.Text = "";
}
The first request that hits an ASP.NET page is usually an HTTP GET request, while ASP.NET buttons and update panel events issue HTTP POST requests. So the code above will clear TextBox1 the first time you access the page, but leave the value alone when receiving requests from itself. (If you really are setting the text box's value to its default - empty - you could just remove the initialization code.)
Wondering if someone here can help.
I have an AJAX tabcontainer which has a number of tabs and each tab contains a user control. When I add a new item from one of the tabs, it is not reflected in the user control in another tab unless a postback occurs. (e.g. the first tab has a listview where I add a new record and the second has a simple form which contains a drop-down which I expect to contain value added from first tab).
How can I make the tabcontainer to refresh its tabs from a usercontrol?
Any help will be most appreciated.
Thanks,
Ali
You could fire an event from your first user control so that the page can handle this event and tell the other usercontrol to databind
Here is a example
<act:TabContainer ID="TabContainer2" runat="server" CssClass="EmployeeProfile" ActiveTabIndex="0">
<act:TabPanel ID="TabPanel1" runat="server" HeaderText="Datos Generales">
<ContentTemplate>
<br />
<uc1:EmployeeGeneralDetails ID="EmployeeGeneralDetails2" runat="server" OnUpdated="EmployeeGeneralDetails2_OnUpdated" />
</ContentTemplate>
</act:TabPanel>
<act:TabPanel ID="TabPanel2" runat="server" HeaderText="Referenias Personales">
<ContentTemplate>
<uc3:EmployeeResumeView ID="EmployeeResumeView2" runat="server" />
</ContentTemplate>
</act:TabPanel>
</act:TabPanel>
protected void EmployeeGeneralDetails2_OnUpdated(object o, EventArgs e)
{
EmployeeResumeView2.DataBind();
}