I have one grid with an ImageButton in an ItemTemplate that download a file and delete a row in the db inside the ItemCommand function. I am using a datasource on the page. All Insert/Update/Delete events are being bound on the server side also.
I am calling the Rebind() method after the data operations, but the grid itself does not show the updated results unless I refresh the page completely.
I've tried disabling the grid viewstate, but it's not working. What do I need to do to get the grid to refresh?
Some code:
<telerik:radgrid runat="server" id="grdId"
allowpaging="True" allowsorting="true" autogeneratecolumns="False" pagesize="10"
cssclass="RadGrid_ModernBrowsers" OnItemCommand="grdId_OnItemCommand"
localizationpath="~/App_GlobalResources" DataSourceID="objDataSource"
enableembeddedskins="true" skin="Telerik" culture="it-IT" allowfilteringbycolumn="true" ViewStateMode="Disabled">
<SelectedItemStyle BorderColor="Yellow"></SelectedItemStyle>
<MasterTableView CommandItemDisplay="Top" DataKeyNames="id"
ClientDataKeyNames="id" ShowGroupFooter="true"
TableLayout="Fixed"
ShowFooter="True" PageSize="10">
<PagerStyle Mode="NextPrevNumericAndAdvanced"></PagerStyle>
<Columns>
(...)
<telerik:GridTemplateColumn AllowFiltering="false">
<HeaderStyle Width="80px" />
<HeaderTemplate>
CV
</HeaderTemplate>
<ItemTemplate>
<asp:ImageButton ID="btnDownload" Width="40px" runat="server" ImageUrl="img/docx.png" CommandName="Download"
AlternateText="Download" ToolTip="Download" CommandArgument='<%# Eval("id")%>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</telerik:GridTemplateColumn>
</Columns>
<CommandItemSettings ShowExportToPdfButton="false"
ShowAddNewRecordButton="false" ShowRefreshButton="false" RefreshText="" />
</MasterTableView>
<ClientSettings>
<Selecting AllowRowSelect="True" />
</ClientSettings>
<GroupingSettings CaseSensitive="false" />
</telerik:radgrid>
<asp:ObjectDataSource ID="objDataSource" runat="server"
TypeName="TypeName"
SelectMethod="Select_Table">
</asp:ObjectDataSource>
Protected Sub Page_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
Try
If Not IsPostBack Then
grdId.DataBind()
End If
Catch ex As Exception
End Try
End Sub
Protected Sub grdId_OnItemCommand(sender As Object, e As GridCommandEventArgs)
Try
If e.CommandName = "Download" Then
Dim Id As Integer = Convert.ToInt32(e.CommandArgument)
Dim scarica As Byte() = CQuery.Select_Download(Id)
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" + "nomefile")
Response.ContentType = "application/msword"
Response.BinaryWrite(scarica)
CQuery.Update_Table(Id) 'This delete the record
grdId.Rebind()
Response.End()
Response.Flush()
End If
Catch ex As Exception
End Try
End Sub
10 Answers, 1 is accepted
Note that the Update/Insert/DeleteCommand events invoke Rebind() implicitly. There is no need to call the method manually after modifying the data. Check out the following article for additional information on the commands that invoke Rebind() implicitly.
Also, I noticed that DataBind() is used for the RadGrid. Note that this method is used only for simple data binding. As the name implies this type of binding is suitable only for the most simple scenarios where features like sorting, filtering, paging, etc. will not be used. Please ensure that DataBound for the grid is not used anywhere in the code-behind.
Moreover, it seems that you are manually creating and sending a response. Note that this would interfere with the standard logic for updating the data and may produce unexpected results.
Regards,
Viktor Tachev
Telerik
Hi,
I'm not using Update event, I'm updating the database in the OnItemCommand of the grid, is the same?
Which command I could use instead of DataBind()? I should use the OnNeedDataSource event?
I'm manually creating and sending a response to download a file, but I can try to temporarily disable that part of code, and only update the database on the item command event.
So now I've modify the code in this way: No Rebind(), OnNeedDataSource instead of DataBind(), no manual creating and sending response.
But still having the same problem...
<telerik:radgrid runat="server" id="grdId"
allowpaging="True" allowsorting="true" autogeneratecolumns="False" pagesize="10"
cssclass="RadGrid_ModernBrowsers" OnItemCommand="grdId_OnItemCommand"
localizationpath="~/App_GlobalResources" DataSourceID="objDataSource"
enableembeddedskins="true" OnNeedDataSource="grdId_NeedDataSource" skin="Telerik" culture="it-IT" allowfilteringbycolumn="true" ViewStateMode="Disabled">
<SelectedItemStyle BorderColor="Yellow"></SelectedItemStyle>
<MasterTableView CommandItemDisplay="Top" DataKeyNames="id"
ClientDataKeyNames="id" ShowGroupFooter="true"
TableLayout="Fixed"
ShowFooter="True" PageSize="10">
<PagerStyle Mode="NextPrevNumericAndAdvanced"></PagerStyle>
<Columns>
(...)
<telerik:GridTemplateColumn AllowFiltering="false">
<HeaderStyle Width="80px" />
<HeaderTemplate>
CV
</HeaderTemplate>
<ItemTemplate>
<asp:ImageButton ID="btnDownload" Width="40px" runat="server" ImageUrl="img/docx.png" CommandName="Download"
AlternateText="Download" ToolTip="Download" CommandArgument='<%# Eval("id")%>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</telerik:GridTemplateColumn>
</Columns>
<CommandItemSettings ShowExportToPdfButton="false"
ShowAddNewRecordButton="false" ShowRefreshButton="false" RefreshText="" />
</MasterTableView>
<ClientSettings>
<Selecting AllowRowSelect="True" />
</ClientSettings>
<GroupingSettings CaseSensitive="false" />
</telerik:radgrid>
<asp:ObjectDataSource ID="objDataSource" runat="server"
TypeName="TypeName"
SelectMethod="Select_Table">
</asp:ObjectDataSource>
Protected Sub grdId_OnItemCommand(sender As Object, e As GridCommandEventArgs)
Try
If e.CommandName = "Download" Then
Dim Id As Integer = Convert.ToInt32(e.CommandArgument)
CQuery.Update_Table(Id) 'This delete the record
End If
Catch ex As Exception
End Try
End Sub
Protected Sub grdId_NeedDataSource(sender As Object, e As GridNeedDataSourceEventArgs)
grdId.DataSource = CQuery.Select_DataFromDb
End Sub
But still having the same problem. On the OnItemCommand I'm updating a row on the database, but I can see the change in the grid only if after I refresh the page. Why?
In the current code it seems that you are using declarative data source for the grid. The DataSourceID points to an ObjectDataSource control. Check out the following article that describes in more detail how you can use bind the RadGrid to a declarative DataSource.
Alternatively you can handle the NeedDataSource event and set the DataSource for the grid there:
It is important to note that you should use only one of the above data-binding methods.
For updating and inserting records you can use the InsertCommand and UpdateCommand events of the grid. Please examine the example below that illustrates how you can implement manual CRUD operations for the grid:
Also, if AJAX is enabled on the page - try to disable it and see if the behavior changes.
Regards,
Viktor Tachev
Telerik
Thanks Victor,
now I'm using only the declarative data source for the grid, but still having the same problem.
The situation here is not a classic UpdateCommand. I've a column of the table that is a varbinary max. Clicking on that column on the grid should start the download of the file and then should start an update to a bit field of the table, to indicate that that file is been downloaded and that row of the grid should disappear (the select of the datasource is like 'select ..... where download = 0', the update is like 'set download = 1') but still I can see the row of the grid disappear only refreshing the page.
I know I should probably use GridAttachmentColumn for this, but I was not able to get it work, so I'm using GridTemplateColumn with an ImageButton inside it. For now I've eliminate the part of code that download the file, so clicking on the button I'm just updating the database setting value = 1 for the bit field of that row, so I expect the row disappear, also without refreshing the page...
How can I disable AJAX on the page?
The updated code:
<
telerik:radgrid
runat
=
"server"
id
=
"grdId"
allowpaging
=
"True"
allowsorting
=
"true"
autogeneratecolumns
=
"False"
pagesize
=
"10"
cssclass
=
"RadGrid_ModernBrowsers"
OnItemCommand
=
"grdId_OnItemCommand"
localizationpath
=
"~/App_GlobalResources"
DataSourceID
=
"objDataSource"
enableembeddedskins
=
"true"
skin
=
"Telerik"
culture
=
"it-IT"
allowfilteringbycolumn
=
"true"
ViewStateMode
=
"Disabled"
>
<
SelectedItemStyle
BorderColor
=
"Yellow"
></
SelectedItemStyle
>
<
MasterTableView
CommandItemDisplay
=
"Top"
DataKeyNames
=
"id"
ClientDataKeyNames
=
"id"
ShowGroupFooter
=
"true"
TableLayout
=
"Fixed"
ShowFooter
=
"True"
PageSize
=
"10"
>
<
PagerStyle
Mode
=
"NextPrevNumericAndAdvanced"
></
PagerStyle
>
<
Columns
>
(...)
<
telerik:GridTemplateColumn
AllowFiltering
=
"false"
>
<
HeaderStyle
Width
=
"80px"
/>
<
HeaderTemplate
>
CV
</
HeaderTemplate
>
<
ItemTemplate
>
<
asp:ImageButton
ID
=
"btnDownload"
Width
=
"40px"
runat
=
"server"
ImageUrl
=
"img/docx.png"
CommandName
=
"Download"
AlternateText
=
"Download"
ToolTip
=
"Download"
CommandArgument='<%# Eval("id")%>' />
</
ItemTemplate
>
<
ItemStyle
HorizontalAlign
=
"Center"
/>
</
telerik:GridTemplateColumn
>
</
Columns
>
<
CommandItemSettings
ShowExportToPdfButton
=
"false"
ShowAddNewRecordButton
=
"false"
ShowRefreshButton
=
"false"
RefreshText
=
""
/>
</
MasterTableView
>
<
ClientSettings
>
<
Selecting
AllowRowSelect
=
"True"
/>
</
ClientSettings
>
<
GroupingSettings
CaseSensitive
=
"false"
/>
</
telerik:radgrid
>
<
asp:ObjectDataSource
ID
=
"objDataSource"
runat
=
"server"
TypeName
=
"TypeName"
SelectMethod
=
"Select_Table"
>
</
asp:ObjectDataSource
>
Protected Sub grdId_OnItemCommand(sender As Object, e As GridCommandEventArgs)
Try
If e.CommandName = "Download" Then
Dim Id As Integer = Convert.ToInt32(e.CommandArgument)
CQuery.Update_Table(Id) 'This update the record
End If
Catch ex As Exception
End Try
End Sub
You can update the data source and send the file to the client. However, the grid cannot refreshed at the same time. This is because the response from the server is passing a file.
In order to achieve the described behavior - download the file and rebind the grid afterwards you would need to use a workaround. You can use server-side logic to update the field in the data source and then send the file to the client.
On the client you would need a way to detect the save file dialog window. When the user closes the window you can use the client-side rebind() method for the MasterTableView.
With that said, I am afraid that the feature you would like to implement would be hard to do. Moreover, the effort may not be worthwhile as you cannot know for sure if the user has actually downloaded the file. You are sending the file from the server, however, you have no control over the user's actions. They can click the Cancel button on the dialog window and disregard the file. However, since you have sent it from the server, the file will be marked as "downloaded" and not shown in the grid.
In order to avoid such cases when the user clicks Cancel in the Save Dialog and never sees the file again I would recommend not to use a field that indicates if the file was downloaded.
Regards,
Viktor Tachev
Telerik
Hi Victor,
I've thought that the problem of grid not refreshing could depend from server passing a file, and for that reason I've temporarily delete the part of code that download the file:
Protected Sub grdCurriculum_OnItemCommand(sender As Object, e As GridCommandEventArgs)
Try
If e.CommandName = "Download" Then
Dim Id As Integer = Convert.ToInt32(e.CommandArgument)
Dim download As Byte() = CQuery.Select_Download(Id)
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" + "cv")
Response.ContentType = "application/msword"
Response.BinaryWrite(download)
CQuery.Update_Table(Id)
Response.End()
Response.Flush()
End If
Catch ex As Exception
End Try
End Sub
And now I'm only updating the data source:
Protected Sub grdCurriculum_OnItemCommand(sender As Object, e As GridCommandEventArgs)
Try
If e.CommandName = "Download" Then
CQuery.Update_Table(Id) 'Update the data source
End If
Catch ex As Exception
End Try
End Sub
But still the grid is not refreshing.. Until manual refreshing the entire page..
The save file dialog window is not a big deal, because is a site's section for admin, that should never click on cancel, but if he do, he can query directly the db to see again that file in the grid..
But until I'm just updating the datasource on the itemcommand event, I should see the grid refreshing..
Downloading a file and refreshing the grid with one request would not be possible. When you send the file to the client you are changing the response. Thus, it is expected that the grid is not updated.
In order to try updating the grid (or any other control on the page) you would need to implement custom logic. You can use client-side logic to detect the Save File dialog in the browser. After this dialog is closed you can call the client-side rebind() method. This will send a new request to the server and the data may be updated.
Note that this behavior is not available out-of-the-box and requires custom implementation. Furthermore, if you decide to implement it you should test it thoroughly and ensure that it works as expected in your scenario.
Have in mind that implementing such scenario may prove hard to do and can result in unexpected behavior.
Regards,
Viktor Tachev
Telerik
Hello Viktor,
thanks, I've understand it. But instead is possible to update the database of the datasource in the itemcommand and refresh the grid with one request, without download the file? Because is what I'm trying to do now, as I wrote in the previous post, but still I have to refresh the entire page after the itemcommand to see the grid refreshing, even if I'm not changing the response anymore.
If you are updating the data in the ItemCommand event handler you would need to call Rebind() for the RadGrid in order for the information to be refreshed.
Regards,
Viktor Tachev
Telerik
Thanks Viktor,
right,I forget that I've delete the Rebind() command too, together with the download file part of code. Now is working!