This is a migrated thread and some comments may be shown as answers.

RadGrid DataSource Switching

8 Answers 295 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Mark
Top achievements
Rank 1
Mark asked on 13 Feb 2014, 11:39 PM
Hi All,

I have an all code-behind solution where I build out the grid columns based upon the DataView acquired from the SqlDataSource.  I'd like to be able to dynamically switch the SqlDataSource for the grid with different drop-down-list options.  I'm doing something like this, but it appears that I'm getting vague errors.  I am re-using the SqlDatasource variable and re-building whenever the User switches the drop-down-list option.  I also re-build my RadGrid's columns using the new DataView from the updated SqlDataSource.  I then rebind(); just like in that link, but I do not autogenerate columns.

Can you anyone please help me?

Thanks,
Mark

8 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 14 Feb 2014, 01:08 PM
Hi Mark,

You can try a similar approach as shown below:

ASPX:
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
    <asp:ListItem Text="empty grid" Value="0" />
    <asp:ListItem Text="1 column grid" Value="1" />
    <asp:ListItem Text="2 column grid" Value="2" />
    <asp:ListItem Text="3 column grid" Value="3" />
</asp:DropDownList>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind_newConnectionString3 %>"
    SelectCommand="SELECT  * FROM [Customers]"></asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind_newConnectionString3 %>"
    SelectCommand="SELECT  * FROM [Orders]"></asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind_newConnectionString3 %>"
    SelectCommand="SELECT  * FROM [Order Details]"></asp:SqlDataSource>

C#:
protected void Page_Init(object sender, System.EventArgs e)
{
   PopulateGridOnPageInit();
}
protected void PopulateGridOnPageInit()
{
   string ddlValue = Request.Form.Get("DropDownList1");
   RadGrid grid = new RadGrid();
   grid.ID = "grid";
   grid.AllowPaging = true
   grid.MasterTableView.AutoGenerateColumns = false;
   grid.MasterTableView.EnableColumnsViewState = false;
   GridBoundColumn boundColumn;
   if (ddlValue != null)
   {
       switch (ddlValue)
       {
           case "0":
               grid.DataSourceID = "";
               grid.DataSource = new object[0];
               break;
           case "1":
               boundColumn = new GridBoundColumn();
               boundColumn.HeaderText = "ContactName";
               boundColumn.DataField = "ContactName";
               boundColumn.UniqueName = "ContactName";
               grid.MasterTableView.Columns.Add(boundColumn);
               grid.DataSourceID = "SqlDataSource1";
               break;
           case "2":
               boundColumn = new GridBoundColumn();
               boundColumn.HeaderText = "OrderID";
               boundColumn.DataField = "OrderID";
               boundColumn.UniqueName = "OrderID";
               grid.MasterTableView.Columns.Add(boundColumn);
               boundColumn = new GridBoundColumn();
               boundColumn.HeaderText = "ShipCity";
               boundColumn.DataField = "ShipCity";
               boundColumn.UniqueName = "ShipCity";
               grid.MasterTableView.Columns.Add(boundColumn);
               grid.DataSourceID = "SqlDataSource2";
               break;
           case "3":
               boundColumn = new GridBoundColumn();
               boundColumn.HeaderText = "UnitPrice";
               boundColumn.DataField = "UnitPrice";
               boundColumn.UniqueName = "UnitPrice";
               grid.MasterTableView.Columns.Add(boundColumn);
               grid.DataSourceID = "SqlDataSource3";
               break;
       }
   }
   else
   {
       grid.DataSourceID = "";
       grid.DataSource = new object[0];
   }
   PlaceHolder1.Controls.Add(grid);
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
   RadGrid grid = PlaceHolder1.FindControl("grid") as RadGrid;
   grid.Rebind();
}

Thanks,
Princy
0
Mark
Top achievements
Rank 1
answered on 14 Feb 2014, 08:06 PM
Princy,

Thank you very much for the reply!

My code looks a little different since it is in SharePoint Web Part.  I create and add the drop down list and datasources in CreateChildControls.  I also call the PopulateGridOnPageInit() method in CreateChildControls.

Unfortunately, I need to have EnableColumnsViewState = true or else I cannot have multi-column filtering.  Right now I'm receiving a full-page error:

[ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index]
   System.Collections.ArrayList.get_Item(Int32 index) +10067188
   Telerik.Web.UI.GridColumnCollection.System.Web.UI.IStateManager.SaveViewState() +208
   Telerik.Web.UI.GridTableView.GetStructureState() +114
   Telerik.Web.UI.RadGrid.SaveTableViewStructure(ArrayList stateList, GridTableView tableView) +47
   Telerik.Web.UI.RadGrid.SaveViewState() +74
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +80
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Control.BuildProfileTree(String parentId, Boolean calcViewState) +404
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3770

I have tried flagging EnableColumnsViewState = false before switching the SqlDataSources and rebinding and then switching it back to EnableColumnsViewState = true, but that has gotten me the same error.

I would also really like to be able to re-used the same SQLDataSource variable, assigning new queries based upon the selected drop down list value.  I actually grab the Data View from the Select Commands and use its columns and column types to generate the new RadGrid's columns.

Thanks,
Mark
0
Marin
Telerik team
answered on 18 Feb 2014, 05:28 PM
Hi,

RadGrid's structure (as well as every other DataBound control) can be dynamically changed only in the Page_Init event. This is required by the ASP.NET framework, because if you create the control on a later event, the ViewState that is automatically loaded by the ASP.NET framework will hold the old structure of the control and look for the old columns because their settings (such as filtering, sorting and so on) have been persisted in the ViewState which causes the out of range exception that you see.
That's why we recommend dynamically creating RadGrid and its entire structure in the OnInit event on every postback of the page.

Regards,
Marin
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
0
Mark
Top achievements
Rank 1
answered on 18 Feb 2014, 06:08 PM
Marin,

Thanks for the information!  If my understanding is correct the only way I can implement the desired "fast-DataSource-switching" is to redirect to the same page with the newly-selected data-source stored in an external location. 

Right now I store the newly selected drop-down-list value (SQL Table Name) in a separate list with the currently logged in User Name.  I redirect to the same page, and before building the grid I query the list based upon the User Name.  The RadGrid is then built out using the stored drop-down-list value.

I suppose that's the best way to do it?

Thanks,
Mark
0
Mark
Top achievements
Rank 1
answered on 18 Feb 2014, 07:16 PM
Marin,

Is there any way to catch this error?  I have a try/catch in ItemCommand, but that does not seem to intercept it.

Thanks,
Mark
0
Marin
Telerik team
answered on 21 Feb 2014, 11:30 AM
Hello,

Yes, this approach looks good so feel free to use it in your application.
The exception from the first post is raised when the ViewState of the page is being saved which normally happens internally after the Page_PreRender event.  The best option to try to intercept the error is to override the SaveViewState method of the page and see if the exception can be caught there.

Regards,
Marin
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
0
Mark
Top achievements
Rank 1
answered on 21 Feb 2014, 01:43 PM
Marin,

Thanks again for the reply!

I'm not sure how I can implement that type of error handling (Page_PreRender) in SharePoint web-part.  Do you have any advice?

Thanks,
Mark
0
Marin
Telerik team
answered on 26 Feb 2014, 10:58 AM
Hello,

The error handling is not related to the Page_PreRender event. It happens internally when the ViewState is saved. Normally these methods should not throw an error so no exception handling of the ViewState persistence should be required. If there is a problem it should be resolved in the code or configuration that is causing it - handling exceptions related to ViewState will not improve the behavior or resolve the issue that's why it is generally not recommended. The preferred approach is remove the cause of the exception rather than simply handling it.

Regards,
Marin
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
Tags
Grid
Asked by
Mark
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
Mark
Top achievements
Rank 1
Marin
Telerik team
Share this question
or