Update a Control in a Callback of Another Control
- 5 minutes to read
A control can update only its own rendering in a callback. When you try to update a control (for instance, change settings or bind it to data) on a callback request of another control, these changes are not applied on the client. In such cases, use one of the solutions listed below.
Update a Control When a Callback of Another Control Is Finished
Every control that supports callbacks implements the BeginCallback and EndCallback client events. Handle the EndCallback event to perform custom actions with another control when a callback is finished. Use an event argument’s command property to determine the action that initiated the callback.
<dx:ASPxGridView ID="ASPxGridView1" runat="server" KeyFieldName="Id" ClientInstanceName="mainGrid" DataSourceID="mainSource">
<SettingsDetail ShowDetailRow="true" />
<Templates>
<DetailRow>
<dx:ASPxGridView ID="gridProducts" ClientInstanceName="gridProducts" runat="server"
DataSourceID="productSource" KeyFieldName="Id">
<ClientSideEvents EndCallback="OnEndCallback" BeginCallback="OnBeginCallback"/>
</dx:ASPxGridView>
</DetailRow>
</Templates>
</dx:ASPxGridView>
function OnBeginCallback(s, e) {
command = e.command;
}
function OnEndCallback(s, e) {
if ((command == "ADDNEWROW" || command == "UPDATEEDIT")) {
mainGrid.Refresh();
}
}
You can use the JSProperties property to send information from the server to the client for further use in client event handlers.
The example below demonstrates how to save an updated row’s key to the JSProperties property on the server and then use it on the client to display information about the updated row.
<dx:ASPxGridView ID="ASPxGridView1" runat="server" DataSourceID="AccessDataSource1"
KeyFieldName="CategoryID" OnRowUpdated="ASPxGridView1_RowUpdated">
<ClientSideEvents EndCallback="OnEndCallBack" />
</dx:ASPxGridView>
<dx:ASPxLabel ID="ASPxLabel1" runat="server" ClientInstanceName="clientLabel" />
protected void Page_Load(object sender, EventArgs e) {
ASPxGridView1.JSProperties["cpIsUpdated"] = "";
}
protected void ASPxGridView1_RowUpdated(object sender, DevExpress.Web.Data.ASPxDataUpdatedEventArgs e) {
if (e.Exception == null) {
((ASPxGridView)sender).JSProperties["cpIsUpdated"] = e.Keys[0];
}
}
function OnEndCallBack(s, e) {
if (s.cpIsUpdated != '') {
clientLabel.SetText('The category ' + s.cpIsUpdated + ' is updated successfully');
}
else {
clientLabel.SetText('');
}
}
The JSProperties property allows you to pass values of the following types: null, DBNull, ValueType, string, IDictionary, and IEnumerable. For more information, see the following topic: Passing Values Between Client and Server Sides.
The example below demonstrates how to create an array of second-level node keys on the server and send it to the client in the JSProperties property.
<dx:ASPxTreeList ID="treeList" runat="server" AutoGenerateColumns="False" ClientInstanceName="treeList"
DataSourceID="AccessDataSource1" KeyFieldName="EmployeeID" ParentFieldName="ReportsTo"
OnDataBound="treeList_DataBound">
<Columns>
<dx:TreeListTextColumn FieldName="LastName" VisibleIndex="0" />
</Columns>
<ClientSideEvents NodeClick="function(s, e) {
if((s.cp_level2Nodeslist).indexOf(e.nodeKey)> -1)
window.location.href ='Default2.aspx?id='+e.nodeKey;
}" />
<SettingsBehavior AutoExpandAllNodes="True" />
</dx:ASPxTreeList>
protected void treeList_DataBound(object sender, EventArgs e) {
ArrayList level2Nodes = new ArrayList();
TreeListNodeIterator iterator = new TreeListNodeIterator(treeList.RootNode);
while (iterator.Current != null) {
if (iterator.Current != treeList.RootNode)
if (iterator.Current.Level == 2)
level2Nodes.Add(iterator.Current.Key);
iterator.GetNext();
}
treeList.JSProperties.Add("cp_level2Nodeslist", level2Nodes);
}
Update Multiple Controls Nested into an ASPxCallbackPanel
The ASPxCallbackPanel control is a container area that allows you to dynamically update its content via callbacks. Call the PerformCallback(parameter) client method to initiate an update callback.
In the example below, two ASPxGridView controls are placed into an ASPxCallbackPanel. The buttons initiate the panel’s callback that updates both grids.
<dx:ASPxCallbackPanel ID="cp" runat="server" ClientInstanceName="cp" OnCallback="cp_Callback">
<PanelCollection>
<dx:PanelContent runat="server">
<dx:ASPxGridView ID="gv1" runat="server" DataSourceID="ads1" KeyFieldName="CategoryID" />
<dx:ASPxGridView ID="gv2" runat="server" DataSourceID="ads2" KeyFieldName="ProductID" />
</dx:PanelContent>
</PanelCollection>
</dx:ASPxCallbackPanel>
<dx:ASPxButton ID="updateBtn" runat="server" Text="Update" AutoPostBack="false">
<ClientSideEvents Click="OnUpdateClick" />
</dx:ASPxButton>
<dx:ASPxButton ID="cancelBtn" runat="server" Text="Cancel" AutoPostBack="false">
<ClientSideEvents Click="OnCancelClick" />
</dx:ASPxButton>
function OnUpdateClick(s, e) { cp.PerformCallback("Update"); }
function OnCancelClick(s, e) { cp.PerformCallback("Cancel"); }
protected void cp_Callback(object sender, CallbackEventArgsBase e) {
switch (e.Parameter) {
case "Update":
gv1.UpdateEdit();
gv2.UpdateEdit();
break;
case "Cancel":
gv1.CancelEdit();
gv2.CancelEdit();
break;
}
}
Use the Equivalent Client API
In many cases, DevExpress ASP.NET controls allow you to replace server-side code with its client-side equivalent.
The example below demonstrates how to use client API to obtain the ProductName field value from a grid control’s focused row and then display a lable for that value. The processOnServer property is set to false
to prevent a postback to the server.
function OnGridFocusedRowChanged(s, e) {
grid.GetRowValues(grid.GetFocusedRowIndex(), 'ProductName', function (value) { lbl.SetText(value) });
e.processOnServer = false;
}
<dx:ASPxLabel ID="ASPxLabel1" runat="server" ClientInstanceName="lbl" />
<dx:ASPxGridView ID="Grid" runat="server" DataSourceID="ProductsDataSource" Width="100%"
ClientInstanceName="grid" SettingsBehavior-AllowFocusedRow="true">
<ClientSideEvents FocusedRowChanged="OnGridFocusedRowChanged" />
<Columns>
<dx:GridViewDataTextColumn FieldName="ProductName" />
<%-- other columns --%>
</Columns>
</dx:ASPxGridView>
Enable Postbacks
Set the EnableCallBacks property to false
to turn off callbacks.
<dx:ASPxGridView ID="ASPxGridView1" runat="server" EnableCallBacks="false" />
In this case, the control initiates postbacks instead of callbacks. When an entire page is refreshed, you can update every control. To refresh only a part of the page, wrap the controls in the asp:UpdatePanel.
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<dx:ASPxGridView ID="ASPxGridView1" runat="server" EnableCallBacks="false" />
// ...
</ContentTemplate>
</asp:UpdatePanel>