Passing value from a user control to the main page aspx - c#

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.

Related

Losing data in LoginView after binding parent Repeater

I'm having some trouble with a LoginView that is nested inside a Repeater in my ASP.NET 4.5 site. The data gets properly bound when the page loads. But if some external event rebinds the repeater, the content inside the LoginView templates doesn't rebind. I've simplified my code down about as much as I can to make it repeatable. Run this page, then click the Rebind Data button. The button labels disappear. How do I get those to properly rebind (ex: show the Text of the data item that it's bound to)? I would think that calling DataBind() on the repeater would rebind all child controls, but I guess not. I tried a couple different iterations of manually binding (and none worked), but would prefer a clean implementation.
RepeaterTest.aspx
<%# Import Namespace="MyNamespace" %>
<asp:Repeater runat="server" ID="MyRepeater">
<ItemTemplate>
<asp:LoginView runat="server">
<LoggedInTemplate>
<asp:Button runat="server" Text='<%# ((Container.Parent as RepeaterItem).DataItem as TestClass).Text %>' /><br />
</LoggedInTemplate>
<AnonymousTemplate>
<asp:Button runat="server" Text='<%# ((Container.Parent as RepeaterItem).DataItem as TestClass).Text %>' /><br />
</AnonymousTemplate>
</asp:LoginView>
</ItemTemplate>
</asp:Repeater>
<asp:Button runat="server" Text="Rebind Data" OnClick="Unnamed_Click" />
RepeaterTest.aspx.cs
namespace MyNamespace
{
public partial class RepeaterTest : System.Web.UI.Page
{
List<TestClass> list = new List<TestClass>()
{
new TestClass("hi"),
new TestClass("hello"),
new TestClass("bonjour"),
new TestClass("hola")
};
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyRepeater.DataSource = list;
MyRepeater.DataBind();
}
}
protected void Unnamed_Click(object sender, EventArgs e)
{
MyRepeater.DataSource = list;
MyRepeater.DataBind();
}
}
public class TestClass
{
public string Text { get; set; }
public TestClass(string text)
{
Text = text;
}
}
}

AsyncPostBackTrigger Just flashing/flicking the UpdatePanel but not updating it

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.

Cloning AJAX TabPanels

I have come across an interesting problem when trying to clone a template panel in my ajax tabcontainer control.
The idea is that i have a custom control on the first tab that lists some things, and to add a new thing you click the new button on the custom control, which raises an event in the control / page that contains the tabcontainer. That control / page then goes about cloning the hidden tabpanel and adding the clone to the tabcontainer.
with this markup I get what I need from both the first tab (containing the list) and any subsequent tabs (templated by the hidden tabpanel ready for cloning) ...
<asp:TabContainer ID="TabContainer1" runat="server">
<asp:TabPanel ID="ui_pnl1" HeaderText="My Panel" runat="server">
<ContentTemplate>
<cc1:myListOfThings ID="list" runat="server" OnMyEvent="CreateTabFromTemplate" />
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="TemplatePanel" runat="server" Visible="false">
<HeaderTemplate>
<span>Hello World</span><asp:LinkButton ID="ui_btnRemove" runat="server" Text="x" />
</HeaderTemplate>
<ContentTemplate>
Some content for my panel
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
Ok now lets assume that on the first panel in my custom control i have a button that raises the "MyEvent" event which in turn calls the method "CreateTabFromTemplate".
Now what I want to do is copy the hidden panel "TemplatePanel" and add it to the tab container.
In my code behind, the method code for adding the new tab panel to my tab container works something like this ...
protected void CreateTabFromTemplate(object sender, EventArgs e)
{
// create a new tab panel
TabPanel newPanel = new TabPanel();
// instantiate the hidden content template from the hidden note panel in the new panel
ui_tpNoteCreator.ContentTemplate.InstantiateIn(newPanel);
// add the panel to the available tabs and select it
TabContainer1.Tabs.Add(newPanel);
TabContainer1.ActiveTab = newPanel;
}
All looking good so far ... but i missed something ... I haven't templated the new tabpanels header ... it seems that all I can do is set the text.
Following this example : http://forums.asp.net/t/1108611.aspx/1 I can do what i'm trying to do but I don't want to write a class that defines my header template I want to instantiate an instance of my markup version and pass that instance to my new panel.
I'm not convinced this can be done ... is this a bug with the control or did i miss something ?!?!
Any ideas?
It turns out i was going about it the wrong way ...
Essentially theres a difference between assigning templates and the databinding process, it's still not perfect because of the data im trying to pass in to my tab templates but here's the basic principal ...
Markup :
<asp:TabContainer ID="TabContainer1" runat="server">
<asp:TabPanel ID="ui_pnl1" HeaderText="My Panel" runat="server">
<ContentTemplate>
<cc1:myListOfThings ID="list" runat="server" OnMyEvent="CreateTabFromTemplate" />
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="TemplatePanel" runat="server" Visible="false">
<HeaderTemplate>
<span>Hello World</span><asp:LinkButton ID="ui_btnRemove" runat="server" Text="x" />
</HeaderTemplate>
<ContentTemplate>
Some content for my panel
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
Code behind :
protected void CreateTabFromTemplate(object sender, EventArgs e)
{
// create a new tab panel
TabPanel newPanel = new TabPanel();
newPanel.HeaderTemplate = TemplatePanel.HeaderTemplate;
newPanel.ContentTemplate = TemplatePanel.ContentTemplate;
// add the panel to the available tabs and select it
TabContainer1.Tabs.Add(newPanel);
TabContainer1.ActiveTab = newPanel;
}
protected void TabContainer_DataBinding(object sender, EventArgs e)
{
foreach(TabPanel panel in TabContainer.Tabs)
{
//identify if this is the correct tab
if(correctTab)
{
// this will find a control anywhere on the panel (eg in both header and content templates)
Label label = panel.FindControl("ControlID") as Label;
label.Text = "Some Business Object Value";
}
}
}
I just tested the following which works as far as I can tell.
Markup:
<asp:TabContainer ID="TabContainer1" runat="server" ViewStateMode="Enabled">
<asp:TabPanel ID="ui_pnl1" HeaderText="My Panel" runat="server">
<ContentTemplate>
<asp:Button ID="btnAddPanel" runat="server" Text="Add Panel" />
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="TemplatePanel" runat="server" Visible ="false">
<HeaderTemplate>
<span>Hello World</span><asp:LinkButton ID="ui_btnRemove" runat="server" Text="X" />
</HeaderTemplate>
<ContentTemplate>
<p>Test Content</p>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
Code behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.btnAddPanel.Click += new EventHandler(btnAddPanel_Click);
}
void btnAddPanel_Click(object sender, EventArgs e)
{
TabPanel newPanel = new TabPanel();
newPanel.HeaderTemplate = TemplatePanel.HeaderTemplate;
TemplatePanel.ContentTemplate.InstantiateIn(newPanel);
TabContainer1.Tabs.Add(newPanel);
TabContainer1.ActiveTab = newPanel;
}
}

how to make a Image-button in the user control execute code in the defaultpage.aspx?

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();
}

Full postback triggered by LinkButton inside GridView inside UpdatePanel

I have a GridView inside of a UpdatePanel. In a template field is a button I use for marking items. Functionally, this works fine, but the button always triggers a full page postback instead of a partial postback. How do I get the button to trigger a partial postback?
<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
<asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
<asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
You need to register each and every LinkButton as an AsyncPostBackTrigger. After each row is bound in your GridView, you'll need to search for the LinkButton and register it through code-behind as follows:
protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);
}
This also requires that ClientIDMode="AutoID" be set for the LinkButton, as mentioned here (thanks to Răzvan Panda for pointing this out).
It's probably not advised but you can make everything on the GridView work asynchronously by excluding the EventName on the AsyncPostBackTrigger so e.g.
<Triggers>
<asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>
This will make the RowCommand event and any other event on the GridView fire asynchronously. Note as well that when you make ClientIDMode="Static" on the GridView it will cause a full postback.
My grid view is in conditional mode.
protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = lnk.UniqueID;
trigger.EventName = "Click";
UpdatePanel2.Triggers.Add(trigger);
}
}
And in the click event of the linkbutton I put:
protected void LinkButton2_Click(object sender, EventArgs e)
{
UpdatePanel2.Update();
}
Put the following element inside system.web element in web.config file
<xhtmlConformance mode="Transitional"/>
MSDN specifies that the UpdatePanel.ChildrenAsTriggers property "[g]ets or sets a value that indicates whether postbacks from immediate child controls of an UpdatePanel control update the panel's content" (see http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx).
Since your LinkButton does not appear to be an "immediate child control," then I would recommend configuring your LinkButton as an explicit AsyncPostBackTrigger.
Below your </ContentTemplate> tag, try adding this:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>
I had an issue where I had one form working fine (page1), another doing whole post backs (page2). Turned out when I made the 2nd page, I had done a bit too much cut/paste, and it still had a javascript call in the form definition.
< form id="form1" runat="server" onsubmit="return checkstuff();">
But checkstuff was not defined in page 2.
deleted the onsubmit, and the partial posts started working.
In the working page - page 1, checkstuff was defined, but was just a stub, which did nothing more than return true. Just for grins, I put an alert in checkstuff, and sure enough, it is called for all submits, partial or not. And, if I changed the stub to just return false, nothing happened at all.
Point in all this, the javascript is still exercised, as if a full page is being submitted. So double check your client side scripts.
this may be old but my solution was to put an update panel inside the itemTemplate and one outside the gridview as well.
the trigger should be the gridview and the outside trigger should be the gridview and PageIndexChanging. Try that.
You need to register each controls for each RowState.
1: Register your controls for RowState = Alternate and Normal)
2: Register your controls for RowState = Edit
3: ...
ASPX:
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:LinkButton runat="server" ID="Btn1"
CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
Code behind :
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow
&& (e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
}
if (e.Row.RowType == DataControlRowType.DataRow
&& e.Row.RowState == DataControlRowState.Edit)
{
LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );
}
}

Categories