I am trying UpdatePanel & AsyncPostBackTrigger on master pages through find control method but problem is when I click on button (UpdateButton) It just flash/flick (No Postback) the UpdatePanle but still it don't update or refresh the gridview (images) inside the updatePanel.
I have placed script Manger on the master page & an AJAX Update panel in a ContentPlaceHolder in the child page. Also, in another ContentPlaceholder there is an asp button (outside of the UpdatePanel).
I want to refresh/reload the AJAX UpdatePanel with this asp button.
Thanks for suggestions.
Child Page Code :-
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager ScriptManager1 = (ScriptManager)Master.FindControl("ScriptManager1");
ContentPlaceHolder cph = (ContentPlaceHolder)Master.FindControl("cp_Button");
Button btnRefresh = (Button)cph.FindControl("btnRefresh");
ScriptManager1.RegisterAsyncPostBackControl(btnRefresh);
}
protected void btnRefresh_Click(object sender, EventArgs e)
{
UpdatePanel1.Update();
}
<%# Page Title="" Language="C#" MasterPageFile="~/InnerMaster.master" AutoEventWireup="true" CodeFile="A.aspx.cs" Inherits="A" Async="true" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="id" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="img12" runat="server" Width="650px" Height="600" ToolTip="A" ImageUrl='<%# Page.ResolveUrl(string.Format("~/Cli/{0}", Eval("image"))) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="cp_Button" Runat="Server">
<asp:Button ID ="btnRefresh" runat="server" onclick="btnRefresh_Click" Height="34" Width="110" Text="More Images" />
</asp:Content>
Hi updated code :- Now on click event whole pages is refreshed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
namespace EProxy
{
public class EventProxy : Control, IPostBackEventHandler
{
public EventProxy()
{ }
public void RaisePostBackEvent(string eventArgument)
{ }
public event EventHandler<EventArgs> EventProxied;
protected virtual void OnEventProxy(EventArgs e)
{
if (this.EventProxied != null)
{
this.EventProxied(this, e);
}
}
public void ProxyEvent(EventArgs e)
{
OnEventProxy(e);
}
}
}
On Master Page Code (btn click):-
protected void btnRefresh_Click(object sender, EventArgs e)
{
ContentPlaceHolder cph = (ContentPlaceHolder)this.FindControl("MainContent");
EventProxy eventProxy = (EventProxy)cph.FindControl("ProxyControl") as EventProxy;
eventProxy.ProxyEvent(e);
}
Web Config :-
<pages maintainScrollPositionOnPostBack="true" enableViewStateMac="true">
<controls>
<add tagPrefix="it" namespace="EProxy" assembly="App_Code"/>
</controls>
</pages>
The reason that it doesn't work is because it's not possible to use a master page control directly as an AsyncPostBackTrigger for a child page control. However, there is a workaround that works by means of a proxy.
First, you need to create the following class (Put it in a seperate .cs file with the same name as the class):
public class EventProxy : Control, IPostBackEventHandler
{
public EventProxy()
{ }
public void RaisePostBackEvent(string eventArgument)
{ }
public event EventHandler<EventArgs> EventProxied;
protected virtual void OnEventProxy(EventArgs e)
{
if (this.EventProxied != null)
{
this.EventProxied(this, e);
}
}
public void ProxyEvent(EventArgs e)
{
OnEventProxy(e);
}
}
This class is a control that will be used to proxy the click event from the master page to the child page in order to refresh the UpdatePanel.
After you created the control, add the following after your UpdatePanel:
<it:EventProxy runat="server" ID="ProxyControl" />
Next, you need to indicate to your website / web application what 'it:EventProxy' is. To do that you need indicate that it is a control by adding it to the <controls> tag in your web.config file:
<pages maintainScrollPositionOnPostBack="true" theme="Default" enableViewStateMac="true">
<controls>
<add tagPrefix="it" namespace="The namespace that you saved the EventProxy class in" assembly="Your Assembly name"/>
</controls>
</pages>
In the above exmaple, set the value of the namespace attribute to the namespace of the EventProxy class, and set the value of the assembly attribute to your solution's name.
After you have done that, add the EventProxy control's EventProxied event as an AsyncPostBackTrigger to your UpdatePanel. Your markup should look something like the following:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ProxyControl" EventName="EventProxied" />
</Triggers>
</asp:UpdatePanel>
<it:EventProxy runat="server" ID="ProxyControl" />
Then, call the following inside of your master page's button (That will be used to refresh the child page UpdatePanel) click event:
protected void btnRefresh_Click(object sender, EventArgs e)
{
EventProxy eventProxy = MasterPageContentPlaceHolder.FindControl("ProxyControl") as EventProxy;
eventProxy.ProxyEvent(e);
}
That's it!
Now what will happen is when you click the button in the master page, it will proxy the event of that click to the child page's EventProxy Control, that will in turn cause the UpdatePanel to refresh since the EventProxy control is one of its AsyncPostBackTriggers.
Place your button in it's own updatePanel or in the same updatePanel that you want to update with that button. Once yo do that, the updatePanel will update without codebehind, the button click will call an async postback for all controls inside all update panels.
Related
Edit: Sadly, nobody seems to know. Maybe this will help clarify my dilemma: I'm trying to implement my own DataList type of control that supports switching from ItemTemplate to EditItemTemplate. The problem occurs when clicking on a button inside the EditItemTemplate -- it doesn't trigger the handler unless you click a second time!
Sorry about the lengthy post. The code is complete, but hopefully with nothing distracting.
I'm trying to create my own User Control that accepts multiple templates. I'm partly following techniques 39 and 40 from "ASP.NET 4.0 in Practice" by Manning. It seems to be working, except the button inside the template isn't bound to the handler until the second click (after one extra postback).
There are four files involved. Default.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%# Register Src="~/TheTemplate.ascx" TagPrefix="TT" TagName="TheTemplate" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<TT:TheTemplate ID="tt" runat="server">
<ATemplate>
<p>This is template A</p>
<asp:Button ID="TemplateAButton" OnClick="TemplateAButton_Click" runat="server" Text="Template A Button" />
</ATemplate>
<BTemplate>
<p>This is template B</p>
<asp:Button ID="TemplateBButton" OnClick="TemplateBButton_Click" runat="server" Text="Template B Button" />
</BTemplate>
</TT:TheTemplate>
<br />
<asp:Button ID="ToggleTemplate" Text="Toggle Template" OnClick="ToggleTemplate_Click" runat="server" />
</div>
</form>
</body>
</html>
Default.aspx.cs:
using System;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Trace.IsEnabled = true;
tt.DataBind();
}
protected void ToggleTemplate_Click(object sender, EventArgs e)
{
tt.TemplateName = (tt.TemplateName == "A") ? "B" : "A";
tt.DataBind();
}
public void TemplateAButton_Click(object sender, EventArgs e)
{
Trace.Write("TemplateAButton_Click");
}
public void TemplateBButton_Click(object sender, EventArgs e)
{
Trace.Write("TemplateBButton_Click");
}
}
And the user control, TheTemplate.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="TheTemplate.ascx.cs" Inherits="TheTemplate" %>
<p>Using template <asp:Literal Text="<%# TemplateName %>" ID="Literal1" runat="server"></asp:Literal></p>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
And finally, TheTemplate.ascx.cs:
using System;
using System.Web.UI;
[ParseChildren(true)]
public class TheTemplateContainer : Control, INamingContainer
{
private TheTemplate parent;
public TheTemplateContainer(TheTemplate parent)
{
this.parent = parent;
}
}
public partial class TheTemplate : System.Web.UI.UserControl, INamingContainer
{
public string TemplateName
{
get { return (string)(ViewState["TemplateName"] ?? "A"); }
set { ViewState["TemplateName"] = value; }
}
[TemplateContainer(typeof(TheTemplateContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ATemplate { get; set; }
[TemplateContainer(typeof(TheTemplateContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate BTemplate { get; set; }
protected override void OnDataBinding(EventArgs e)
{
TheTemplateContainer container = new TheTemplateContainer(this);
if (TemplateName == "A")
ATemplate.InstantiateIn(container);
else if (TemplateName == "B")
BTemplate.InstantiateIn(container);
PlaceHolder1.Controls.Clear();
PlaceHolder1.Controls.Add(container);
EnsureChildControls();
base.OnDataBinding(e);
}
}
When you first run it, you will see ATemplate being used:
If you click on the Toggle Template button, all the text is correctly rendered:
But clicking on either "Template A Button" or "Template B Button" will not trigger the OnClick handler on the first try:
It will work on the second click:
Does the problem have to do with where .DataBind() is being called?
I'm not quite sure I understand it, but the problem has to do with how newly-added controls go through the "catch-up" events. Removing PlaceHolder1 and adding it programmatically solves the issue. TheTemplate.ascx becomes:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="TheTemplate.ascx.cs" Inherits="TheTemplate" %>
<p>Using template
<asp:Literal Text="<%# TemplateName %>" ID="Literal1" runat="server"></asp:Literal></p>
... and in TheTemplate.ascx.cs, replace OnDataBinding like this:
protected override void OnDataBinding(EventArgs e)
{
TheTemplateContainer container = new TheTemplateContainer(this);
if (TemplateName == "A")
ATemplate.InstantiateIn(container);
else if (TemplateName == "B")
BTemplate.InstantiateIn(container);
System.Web.UI.WebControls.PlaceHolder PlaceHolder1 = new System.Web.UI.WebControls.PlaceHolder();
//PlaceHolder1.Controls.Clear();
PlaceHolder1.Controls.Add(container);
this.Controls.Clear();
this.Controls.Add(PlaceHolder1);
EnsureChildControls();
base.OnDataBinding(e);
}
In the future, if I ever feel like I need to add controls dynamically, I will also create a PlaceHolder dynamically and use that as the root. When PlaceHolder is populated, I will then add it to the page.
I have spent lot of time to investigate how to update label outside Update panel. And finally found something but it does not update label. It works fine if we refresh the page. Please let me know error in code or any new way of doing this. Please find my code below. I think need add some more code for script manager Or dataItem()
Thank you guys for reply!
Code behind file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class scriptMgr : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void timer_Tick(object sender, EventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack)
{
ScriptManager1.RegisterDataItem(Label3, "Hi");
}
}
}
}
Aspx page
<div>
<asp:Label ID="Label3" runat="server" Text="krwelkr"></asp:Label>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript" language="javascript">
enter code here
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(PageLoadingHandler);
function PageLoadingHandler(sender, args) {
var dataItems = args.get_dataItems();
if ($get('Label3') != null)
$get('Label3').innerHTML = dataItems['Label3'];
}
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
</div>
If you need to update the label with dynamic content from the server, have it wrapped in the same updatepanel or another updatepanel.
If the Label text is not dynamic, you could probably use JS to alter the label before firing the right event.
Also, UpdatePanels do "cause postbacks". its just that you don't notice them.
Or you can do this way:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode=Conditional>
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
Code-behind:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "Updated";
}
You need to use the pageLoaded event of the PageRequestManager.
The pageLoading event is raised before any content on the page is updated. So your changes made in pageLoading event will be lost if you also make changes to label's content anywhere else.
Therefore, when using the pageLoaded event which is raised after all content on the page is refreshed as a result of either a synchronous or an asynchronous postback, chnages made inside this event will overwrite all changes made anywhere else and will be the final.
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoadedHandler)
function PageLoadedHandler(sender, args) {
var dataItems = args.get_dataItems();
if ($get('Label3') != null)
// set Label3 to your actual values. You can test/debug by adding
// any test value
$get('Label3').innerHTML = "TTTTestingggg";
}
</script>
Add the register script in code behind event,
protected void timer_Tick(object sender, EventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack)
{
//ScriptManager1.RegisterDataItem(Label3, "Hi");
ScriptManager.RegisterStartupScript(this, this.GetType(), "setLabelOrAnyName", "jQuery(function($) { $('#Label3').text('Whatever')});", true);
}
}
This should work.
Incase if you are not using jQuery library replace code with simple javascript.
Im having a .Master page with
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
<ContentTemplate>
<asp:ContentPlaceHolder ID="MasterIndhold_Member" runat="server">
</asp:ContentPlaceHolder>
And inside the ContentPlaceHolder I got an Panel with a FileUpload. The thing is that the FileUpload doesn't find the file. Here I want to add RegisterAsyncPostBackControl to the Scriptmanager, but how do I do this when the panel is on another page?
The nested page code looks like this
<asp:Content ID="Content3" ContentPlaceHolderID="MasterIndhold_Member" runat="server">
<asp:panel runat="server" ID="Panel_MyProfile_Member" Visible="false">
<asp:FileUpload ID="File1" runat="server" />
<asp:LinkButton ID="LinkUploadImageMember" runat="server" onclick="LinkUploadImageMember_Click">Upload</asp:LinkButton>
And the CodeBehind for the FileUpload Looks like this
protected void LinkUploadImageMember_Click(object sender, EventArgs e)
{
if (File1.HasFile == true)
{
if ((File1.PostedFile.FileName.EndsWith(".jpg")) || (File1.PostedFile.FileName.EndsWith(".jpeg")) || (File1.PostedFile.FileName.EndsWith(".png")))
{
byte[] input = File1.FileBytes;
Bruger.UploadImage(input, int.Parse(Request.QueryString["ID"]));
}
}
}
Please keep code examples to C# and ASP.NET as I'm new to this stuff ^^
Thanks
You could also use the ScriptManagerProxy class if you need a ScriptManager on your content page, but I'm not sure whether you need this at all. Do you really need an UpdatePanel on every content page? (because you declared it on the master page). I think it might be better to declare the UpdatePanel within the content page.
Try to define a trigger for your linkbutton, otherwise HasFiles is always false
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:PostBackTrigger ControlID="LinkUploadImageMember" />
</Triggers>
<ContentTemplate>
<asp:FileUpload ID="File1" runat="server" />
<asp:LinkButton ID="LinkUploadImageMember" runat="server" Text=" upload " />
</ContentTemplate>
</asp:UpdatePanel>
If you cannot remove the UpdatePanel from the Masterpage, you could expose a property on the masterpage that gives access the updatepanel, like this:
public UpdatePanel MyUpdatePanel
{
get { return UpdatePanel1; }
}
From the contentpage you can access the update panel and update the triggers programmatically:
protected void Page_Load(object sender, EventArgs e)
{
((Site)Master).MyUpdatePanel.Triggers.Add(new PostBackTrigger() {
ControlID = LinkUploadImageMember.UniqueID });
}
I've a problem to pass a value from my user control to the aspx page. In the user control there is 2 textbox with a button to searh a customer and a gridview to show the results. When the select button is clicked I want to pass the value to the page.aspx. There is a button that when clicked, a modalpopupextender appears. Thi is the code:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="searchCommittente.ascx.cs" Inherits="Assistenze_ControlliCustom_searchCommittente" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:TextBox runat="server" ID="lblNomeCommittente"/>
<asp:Button runat="server" ID="btnShow" Text="Cerca Committente" />
<asp:ModalPopupExtender runat="server" Y="155" ID="mpeCercaCommittente" TargetControlID="btnShow" OkControlID="btnSearch"
PopupControlID="pnlPopupContainer" CancelControlID="spnClose" BehaviorID="mpeCercaCommittente"/>
<asp:Panel runat="server" ID="pnlPopupContainer" CssClass="pnlPopupContainer">
<span id="spnClose"></span>
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<h2>Find Customer</h2>
<%=DateTime.Now%>
<asp:Panel runat="server" >
Referente :
<asp:TextBox ID="txtNomeReferente" runat="server" AutoPostBack="true"></asp:TextBox>
Committente :
<asp:TextBox ID="txtNomeCommittente" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Search" onclick="btnSearch_Click"
CausesValidation="false" UseSubmitBehavior="false" />
</asp:Panel>
<p />
<asp:GridView ID="gvCommittenti" runat="server" AutoGenerateColumns="False"
AllowPaging="true" EnableViewState="False"
DataKeyNames="CustomerID"
DataSourceID="EntityDataSourceCommittenti"
OnSelectedIndexChanged="gvCommittenti_SelectedIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="CustomerID" HeaderText="Customer ID" SortExpression="CustomerID"/>
<asp:BoundField DataField="CompanyName" HeaderText="Company Name" SortExpression="CompanyName" />
<asp:BoundField DataField="ContactName" HeaderText="Contact Name" SortExpression="ContactName" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
<asp:EntityDataSource ID="EntityDataSourceCommittenti" runat="server" OrderBy=""
ConnectionString="name=NorthwindEntitiesCommittenti"
DefaultContainerName="NorthwindEntitiesCommittenti" EntityTypeFilter=""
EntitySetName="Customers" EnableFlattening="false"
Select="it.[CustomerID], it.[CompanyName], it.[ContactName], it.[Phone]" Where="it.[CompanyName] like #CompanyName"
AutoGenerateOrderByClause="True">
<WhereParameters>
<asp:FormParameter FormField="txtNomeCommittente" Name="CompanyName" DefaultValue="%" Type="String" />
</WhereParameters>
<OrderByParameters>
<asp:Parameter DefaultValue="it.[CustomerID]" Name="prmCustomerID"
Type="String" />
</OrderByParameters>
</asp:EntityDataSource>
I've tried with this event, but nothing happens:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgse)
{
((TextBox)Page.FindControl("ctl00$Body$txtTitolo")).Text = (string)gvCustomers.DataKeys[e.NewSelectedIndex][0];
mpeCercaCommittente.Hide();
}
Where txtTitolo is a textbox on the main aspx page.
Someone can help me that are 3 days I'm blocked on this.
Thanks in advance.
-----EDIT----
Thanks Brian,
I've made some changes to your post, but now it's finally working.
As you said I put the ThextoBox in un updatepanel:
Than I created inside the user Control the Delgate (I d'ont know but if I done as you wrote me, Visual studio 2010 went frozen):
public partial class Assistenze_ControlliCustom_searchCommittente : System.Web.UI.UserControl
{
public delegate void CommittenteSelectedHendler(string text);
public event CommittenteSelectedHendler custom;
.........................
Now when I click on the select button of the gridview, this function starts:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgs e)
{
if (custom != null)
{
string eventText = (string)gvCommittenti.DataKeys[e.NewSelectedIndex][0];
custom(eventText);
}
mpeCercaCommittente.Hide();
}
In this way the main page update the textbox using the registered event
that fires the procedure setTextBox:
public partial class Assistenze_AssistenzeIngresso : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ucCommittenteSearch.custom += new Assistenze_ControlliCustom_searchCommittente.CommittenteSelectedHendler(setTextBox);
chkFattura.Attributes.Add("onclick", "return cmode_check(this)");
Master.IdBody = "assistenze";
}
private void setTextBox(string text)
{
//set the text
txtCommittenteViewName.Text = text;
//update the page to reflect the change:
UpdatePanel1.Update();
}
.....................................................
Mission completed!
First thing to remember is that you are updating the page using a partial post, so the server-side display of the textbox is not updated on the main page, which could be part of your problem. Assuming that is not the only problem, the best way I've done this in the past is to use delegated events that the control can raise and the page subscribes to on the control.
To start, on your main page, make sure that you have the textbox you want updated inside of an update panel that is also marked with conditional update:
<asp:UpdatePanel ID="upd1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="txtTitolo" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
in the code-behind on the main page (at namespace level, NOT at page level), add the delegate for the event:
namespace WebUserControlTalksToPage
{
//create the delegate to handle user-control updating page controls
public delegate void setPageText(string text);
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// we'll add here in a second.
}
}
}
Next, go into the user control that you want to talk to the page (in your case the one with the gridview) and add the event to be raised:
public partial class SomeUserControl : System.Web.UI.UserControl
{
//create a public event on the delegate type defined in the namespace:
public event setPageText reporter;
public void Page_Load(object sender, EventArgs e)
{
//....
}
}
Next, add the reporter event to the event you want to raise it (in your case, the gvCommittenti_SelectedIndexChanged event:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgse)
{
//NOTE: you can add this in any event where you want
//to raise the event to the subscribers.
if (reporter != null)
{
//note: I separated this because I'm not testing your string. You will need
// to make sure the string you are sending is correct:
string eventText = (string)gvCustomers.DataKeys[e.NewSelectedIndex][0];
//this will raise the event to all subscribers:
reporter(eventText);
}
}
Next, you need to add the handler back on the page to respond (subscribe) to the event. In the main page_load, add the event:
protected void Page_Load(object sender, EventArgs e)
{
//'reporter' is the name of the event on the control
//setPageText is the name of the delegate event
//setTextBox is the event we will write to handle the raised event from the user control
//SomeUserControl1 is a variable name, replace with your UC name as defined in your page
this.SomeUserControl1.reporter += new setPageText(setTextBox);
}
Finally, you need to handle the event that is raised by the user control in the main page. Since the user control is doing a partial-page postback, you'll want to make sure to update the panel that contains the text as mentioned at the start of my response:
private void setTextBox(string text)
{
//set the text
this.txtTitolo.Text = text;
//update the page to reflect the change:
upd1.Update();
}
This should solve your problems. Let me know if anything about the response is unclear or confusing.
1-I have three user controls.
2-I added them to AJAX TabContainer on my default.aspx page
<asp:TabContainer ID="TabContainer1" runat="server">
<asp:TabPanel runat="server" ID="GroupOne">
<HeaderTemplate>
1
</HeaderTemplate>
<ContentTemplate>
<SUR:GroupOne ID="group1" runat="server" />
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="GroupTwo" runat="server">
<HeaderTemplate>
2
</HeaderTemplate>
<ContentTemplate>
<SUR:GroupTwo is="group2" runat="server" />
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="GroupThree" runat="server">
<HeaderTemplate>
3
</HeaderTemplate>
<ContentTemplate>
<SUR:GroupThree ID="grup3" runat="server" />
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
3- in the first user control i have image-button
<asp:ImageButton ID="ImageButton1" runat="server" />
4- I have this code in my default.vb
Public Sub movit()
GroupThree.Enabled = True
TabContainer1.ActiveTab = GroupThree
End Sub
so how can i execute that sub when i click on the image button in the user-control??
I believe you need to use a delegate to achive this. You can try followings
In your ascx.cs or vb file Add a delegate inside the namespace but outside the UserControl class.
public delegate void ImageButtonClickEventHandler(Object sender, EventArgs args);
Inside UserControl class add an event using delegate.After that call the delegate inside ImageButtonClick event.
public event ImageButtonClickEventHandler ImageButtonClickEvent;
private void imageButton_Click(object sender, System.EventArgs e)
{
if(ImageButtonClickEvent!= null)
{
ImageButtonClickEvent(sender,e);
}
}
In your aspx page add this inside page load event.
UserControl1.ImageButtonClickEvent+=new ImageButtonClickEventHandler(UserControl1_ImageButtonClickEvent);
Finally declare UserControl1_ImageButtonClickEvent function
private void UserControl1_ImageButtonClickEvent(Object sender, EventArgs args)
{
//Call your methods
}
From your designer, double-click the button, this will wire up an event-handler (ImageButton1_Click) and set the onclick property of your imagebutton to ImageButton1_Click.
In the code behind of your page, just call movit() from the generated eventhandler.
[Edit]
Didn't see that the image button was in a user control.
The way to go would be to add an Event to your user control. Raise it when the user clicks the imagebutton. In the page, handle the new event of the user control and call the movit() function.
What aboiut..
1) add an event handler to the user control
public event EventHandler Click
{
add
{
ImageButton1.Click += value;
}
remove
{
ImageButton1.Click -= value;
}
}
2) subscribe to this event from the page you are using the control - default.aspx
<user:control runat="server" ID="uc" OnClick="uc_OnClick" />
and
protected void uc_OnClick(object sender, EventArgs e)
{
movit();
}