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

RadGrid client side databind with programmatic structure is duplicating columns on postback

11 Answers 326 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tilak
Top achievements
Rank 1
Tilak asked on 19 May 2010, 12:40 AM

I am making a simple grid control using the radgrid which derives its structure(columns) from an xml and databind using client side web serivce. It works fine, render intially, paging/sorting work fine, I implement the client OnRowDataBound event and render hyperlinks also. When a postback happens from any other buttons on the page, the columns in the grid are duplicated.

Following is my simplified code:
aspx:

<asp:Button ID="btnPostBack" runat="server" Text="PostBack" /> 
        <telerik:RadGrid ID="grid" runat="server" GridLines="None" AllowFilteringByColumn="false" 
            AllowSorting="true" AllowPaging="true" PageSize="10" AutoGenerateColumns="false">  
            <ClientSettings> 
                <DataBinding SelectMethod="GetResults" /> 
                <ClientEvents /> 
            </ClientSettings> 
            <MasterTableView Width="100%" AutoGenerateColumns="false">  
            </MasterTableView> 
            <PagerStyle Mode="NextPrevAndNumeric" /> 
        </telerik:RadGrid> 

Code behind:
protected override void OnInit(EventArgs e)  
        {  
            base.OnInit(e);  
            FillColumns();  
        }  
        [Serializable]  
        public class Field  
        {  
            public String ColumnName { getset; }  
            public String DisplayName { getset; }  
        }  
        private void FillColumns()  
        {  
            List<Field> fields = new List<Field>  
            {  
                new Field { DisplayName = "ID", ColumnName = "ID" },  
                new Field { DisplayName = "Name", ColumnName = "Name" },  
                new Field { DisplayName = "Description", ColumnName = "Description" },  
                new Field { DisplayName = "Location", ColumnName = "Location" }  
            };  
            grid.MasterTableView.Columns.Clear();  
            foreach (var field in fields)  
            {  
                GridBoundColumn col = new GridBoundColumn();  
                grid.MasterTableView.Columns.Add(col);  
                col.DataField = field.ColumnName;  
                col.HeaderText = field.DisplayName;  
                if (field.ColumnName == "ID")  
                    col.DataType = Type.GetType("System.Int32");  
                  
            }  
        }  
        protected void Page_Load(object sender, EventArgs e)  
        {  
            grid.ClientSettings.DataBinding.Location = ResolveUrl("~/SearchService.asmx");  
        } 

ASMX:
[WebService(Namespace = "http://tempuri.org/")]  
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
    [System.ComponentModel.ToolboxItem(false)]  
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.   
    [System.Web.Script.Services.ScriptService]  
    public class SearchService : System.Web.Services.WebService  
    {  
        [WebMethod(EnableSession = true)]  
        public Dictionary<String, Object> GetResults(  
            int startRowIndex, int maximumRows,  
            List<GridSortExpression> sortExpression,  
            List<GridFilterExpression> filterExpression)  
        {  
            DataTable dt = new DataTable();  
            dt.Columns.Add("ID", Type.GetType("System.Int32"));  
            dt.Columns.Add("Name");  
            dt.Columns.Add("Description");  
            dt.Columns.Add("Location");  
 
            for (int i = 0; i < 35; i++)  
            {  
                System.Data.DataRow dr = dt.NewRow();  
                dr["ID"] = i;  
                dr["Name"] = "Name" + i;  
                dr["Description"] = "Description" + i;  
                dr["Location"] = "Location" + i;  
                dt.Rows.Add(dr);  
            }  
 
            return new Dictionary<String, Object>  
            {  
                { "Data", RowsToDictionary(dt, dt.Select(string.Format(" ID > {0} and ID < {1}", startRowIndex.ToString(), (startRowIndex + maximumRows).ToString()))) },  
                { "Count", dt.Rows.Count }  
            };  
        }  
        private static List<Dictionary<stringobject>> RowsToDictionary(DataTable table, DataRow[] rows)  
        {  
            List<Dictionary<stringobject>> objs =  
                new List<Dictionary<stringobject>>();  
            foreach (DataRow dr in rows)  
            {  
                Dictionary<stringobject> drow = new Dictionary<stringobject>();  
                for (int i = 0; i < table.Columns.Count; i++)  
                {  
                    drow.Add(table.Columns[i].ColumnName, dr[i]);  
                }  
                objs.Add(drow);  
            }  
 
            return objs;  
        } 


Note, this is a simplified version and the control has more complicated things which are not relevant here.

Thank you,
Tilak

11 Answers, 1 is accepted

Sort by
0
Iana Tsolova
Telerik team
answered on 19 May 2010, 11:52 AM
Hi Tilak M,

Please note that when RadGrid is declaratively added, and you want to define the structure dynamically, you should add the columns to the MasterTableView columns collection in the Page_Load event and only on initial load. You can find more information here.

Check it out and let me know if it works for you.

All the best,
Iana
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Tilak
Top achievements
Rank 1
answered on 19 May 2010, 07:50 PM
Ok, Now I have the grid added programmatically instead of declaretively and it works fine.
Although these are the following issues I need help on:
I have the column alignment based on the datatype, like numeric to right, dates centered and the rest left aligned.

1. When we change the page size from say 10 to 20, the new 10 records are always left aligned. Attahced screen shot.
2. How to set the intial sorting, let's say Description column descending.
3. The grid loses its state on postback. It goes to page 1 with the default page size.

Here is my changed codebehind:
RadGrid grid;  
        protected override void OnInit(EventArgs e)  
        {  
            base.OnInit(e);  
            grid = new RadGrid();  
            SetGridProperties();  
            FillColumns();  
            phGrid.Controls.Add(grid);  
        }  
 
        private void SetGridProperties()  
        {  
            grid.AllowFilteringByColumn = false;  
            grid.MasterTableView.AutoGenerateColumns = false;  
            grid.AllowPaging = true;  
            grid.AllowSorting = true;  
            grid.GridLines = GridLines.Both;  
            grid.PagerStyle.Mode = GridPagerMode.NextPrevAndNumeric;  
            grid.ClientSettings.DataBinding.SelectMethod = "GetResults";  
            grid.ClientSettings.DataBinding.Location = ResolveUrl("~/SearchService.asmx");  
        }  
        [Serializable]  
        public class Field  
        {  
            public String ColumnName { getset; }  
            public String DisplayName { getset; }  
            public Type DataType { getset; }  
        }  
        private void FillColumns()  
        {  
            List<Field> fields = new List<Field>  
            {  
                new Field { DisplayName = "ID", ColumnName = "ID", DataType = typeof(Int32)},  
                new Field { DisplayName = "Name", ColumnName = "Name", DataType = typeof(string) },  
                new Field { DisplayName = "Description", ColumnName = "Description", DataType = typeof(string) },  
                new Field { DisplayName = "Location", ColumnName = "Location",  DataType = typeof(string) },  
                new Field { DisplayName = "UpdatedDate", ColumnName = "UpdatedDate", DataType = typeof(DateTime) },  
            };  
            grid.MasterTableView.Columns.Clear();  
            foreach (var field in fields)  
            {  
                GridBoundColumn col = GetGridColumn(field.DataType);  
                grid.MasterTableView.Columns.Add(col);  
                col.DataField = field.ColumnName;  
                col.HeaderText = field.DisplayName;  
            }  
        }  
        public static GridBoundColumn GetGridColumn(Type type)  
        {  
            switch (Type.GetTypeCode(type))  
            {  
                case TypeCode.Int32:  
                    {  
                        GridNumericColumn col = new GridNumericColumn { DataType = type };  
                        col.ItemStyle.HorizontalAlign = HorizontalAlign.Right;  
                        return col;  
                    }  
                case TypeCode.DateTime:  
                    {  
                        GridDateTimeColumn col = new GridDateTimeColumn { DataType = type, DataFormatString = "{0:" + DateTimeFormatInfo.CurrentInfo.ShortDatePattern + "}" };  
                        col.ItemStyle.HorizontalAlign = HorizontalAlign.Center;  
                        return col;  
                    }  
                default:  
                    return new GridBoundColumn { DataType = type };  
            };  
        } 

ASPX:
<div> 
        <asp:Button ID="btnPostBack" runat="server" Text="PostBack" /> 
        <asp:PlaceHolder ID="phGrid" runat="server"></asp:PlaceHolder> 
    </div> 

WebService:
[WebMethod(EnableSession = true)]  
        public Dictionary<String, Object> GetResults(  
            int startRowIndex, int maximumRows,  
            List<GridSortExpression> sortExpression,  
            List<GridFilterExpression> filterExpression)  
        {  
            DataTable dt = new DataTable();  
            dt.Columns.Add("ID", Type.GetType("System.Int32"));  
            dt.Columns.Add("Name");  
            dt.Columns.Add("Description");  
            dt.Columns.Add("Location");  
            dt.Columns.Add("UpdatedDate");  
 
            for (int i = 0; i < 35; i++)  
            {  
                System.Data.DataRow dr = dt.NewRow();  
                dr["ID"] = i;  
                dr["Name"] = "Name" + i;  
                dr["Description"] = "Description" + i;  
                dr["Location"] = "Location" + i;  
                dr["UpdatedDate"] = DateTime.Today.AddDays(i).ToShortDateString();  
                dt.Rows.Add(dr);  
            }  
 
            return new Dictionary<String, Object>  
            {  
                { "Data", RowsToDictionary(dt, dt.Select(string.Format(" ID > {0} and ID < {1}", startRowIndex.ToString(), (startRowIndex + maximumRows).ToString()))) },  
                { "Count", dt.Rows.Count }  
            };  
        }  
        private static List<Dictionary<stringobject>> RowsToDictionary(DataTable table, DataRow[] rows)  
        {  
            List<Dictionary<stringobject>> objs =  
                new List<Dictionary<stringobject>>();  
            foreach (DataRow dr in rows)  
            {  
                Dictionary<stringobject> drow = new Dictionary<stringobject>();  
                for (int i = 0; i < table.Columns.Count; i++)  
                {  
                    drow.Add(table.Columns[i].ColumnName, dr[i]);  
                }  
                objs.Add(drow);  
            }  
            return objs;  
        } 


Thank you,
Tilak
0
Accepted
Iana Tsolova
Telerik team
answered on 25 May 2010, 03:29 PM
Hello Tilak,

Please find my answer to your questions in the other thread you have posted on the same subject.
And to avoid duplicate posts I suggest that we continue discussing the issue in question there as well.

Greetings,
Iana
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
mahesh
Top achievements
Rank 1
answered on 21 Jul 2010, 02:07 PM
           
is it possible to set  these to settings using javascript  on a button click  ?

            grid.ClientSettings.DataBinding.SelectMethod = "GetResults";  
            grid.ClientSettings.DataBinding.Location = ResolveUrl("~/SearchService.asmx");
0
Tilak
Top achievements
Rank 1
answered on 22 Jul 2010, 05:15 AM
Yes, on the button click event get the RadGrid client object and follow the client API for RadGrid to implement this.
0
mahesh
Top achievements
Rank 1
answered on 22 Jul 2010, 05:56 AM

tilak, some how i am getting the GridClient Id  and able to assign client settings  as shown in below code  from there i am not 
able to proceed .. kindly guide me.

 function testit() {
        var ctrlid = document.getElementById('<%=txtID.ClientID%>').value;
        var ctrl = $find(ctrlid);
        ctrl.ClientSettings.DataBinding.Location = "/Services/mySearchService.asmx";
        ctrl.ClientSettings.DataBinding.SelectMethod = "SearchGridResults";


        /// Form here How can i call Data_Binding event which accepts  two arguments   sender and event args

    }

0
Iana Tsolova
Telerik team
answered on 22 Jul 2010, 12:30 PM
Hello mahesh,

ClientSettings.DataBinding.Location and ClientSettings.DataBinding.SelectMethod are server-side properties. On the client you can use the set_dataSource() and dataBind() methods.
Find more information in the below articles:

http://www.telerik.com/help/aspnet-ajax/set-datasource.html
http://www.telerik.com/help/aspnet-ajax/databind.html
http://demos.telerik.com/aspnet-ajax/grid/examples/client/databinding/defaultcs.aspx

Regards,
Iana
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
mahesh
Top achievements
Rank 1
answered on 22 Jul 2010, 12:42 PM
Dear Telerik Team,
  
How about the part which is highlighted in Bold.
since i am using Json webservice approch  how can i pass argument to set_dataSource() method.( i should not use any Pagemethods  to get result).

function
assignDataSource()
{
  var masterTable = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
  masterTable.set_dataSource(<some_data_source_of_the_specified_type_above>);
  masterTable.dataBind();
}
Kindly help me.

0
Iana Tsolova
Telerik team
answered on 26 Jul 2010, 01:42 PM
Hi mahesh,

Please see how the QuoteWebService GetListOfStockQuotes() select method is called on the client and how the grid is bound in the updateGrid() method using the previously mentioned methods in this demo.

I hope this helps.

Best wishes,
Iana
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
mahesh
Top achievements
Rank 1
answered on 27 Jul 2010, 11:12 AM
Dear Telerik,

As per the demo you have provided to me in your Previous Post  , i tried to execute the following stuff
I am getting  an error like "SearchService is undefined".(searchservice is my webservice name) .
Kindly let me know where the things are going wrong in my code.


<%

@ Control Language="C#" AutoEventWireup="true" CodeBehind="NewClientSideGrid.ascx.cs" Inherits="TelerikWorkouts.NewClientSideGrid" %>

 

<%

@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>

 

<%

@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajax" %>

 

<

 

telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">

 

 

<script type="text/javascript">

 

 

//<![CDATA[

 

 

function pageLoad(sender, args) {

 

setInterval(

"SearchService.GetData2(updateGrid)", 10);

 

 

}

 

function updateGrid(result) {

 

 

var tableView = $find("<%= RadGrid1.ClientID %>").get_masterTableView();

 

tableView.set_dataSource(result);

tableView.dataBind();

}

 

 

</script>

 

 

</telerik:RadCodeBlock>

 

 

 

<asp:ScriptManager ID="RadScriptManager" runat="server" >

 

 

<Services>

 

 

<asp:ServiceReference Path="~/searchservice.asmx" />

 

 

</Services>

 

 

</asp:ScriptManager>

 

<

 

telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" EnableSkinTransparency="true"

 

 

BackgroundPosition="Center" Skin="Default" />

 

<

 

telerik:RadGrid ID="RadGrid1" AutoGenerateColumns="false" runat="server">

 

 

<MasterTableView TableLayout="Fixed">

 

 

<Columns>

 

 

<telerik:GridBoundColumn AllowFiltering="false" AllowSorting="false" DataField="Name" DataType="System.String" HeaderText="Name" Visible="true">

 

 

</telerik:GridBoundColumn>

 

 

<telerik:GridBoundColumn AllowFiltering="false" AllowSorting="false" DataField="Age" DataType="System.Int32" HeaderText="Age" Visible="true">

 

 

</telerik:GridBoundColumn>

 

 

</Columns>

 

 

</MasterTableView>

 

 

<ClientSettings>

 

 

<ClientEvents OnCommand="function(){}" />

 

 

</ClientSettings>

 

 

</telerik:RadGrid>

 

0
Iana Tsolova
Telerik team
answered on 28 Jul 2010, 12:24 PM
Hello mahesh,

Can you try moving the javascript code after the ScriptManager declaration and see if the error persists?

All the best,
Iana
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Grid
Asked by
Tilak
Top achievements
Rank 1
Answers by
Iana Tsolova
Telerik team
Tilak
Top achievements
Rank 1
mahesh
Top achievements
Rank 1
Share this question
or