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

[Solved] Question About Creating GridButtonColumn at Runtime

3 Answers 119 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Golem
Top achievements
Rank 1
Golem asked on 28 Jul 2009, 06:12 PM
I have a "best practices" question I was hoping to get some insight on...

My project has a user control ("GridPanel") which consists of a RadGrid, plus a few other controls (such as an object data source) for controlling the behavior of the grid, custom paging, sorting, filtering, and AJAX.

I have created another user control ("ParentChildGridPanel") which nests two "GridPanel" user controls, one as the parent, and one as the child.  So far so good...

In the ParentChildGridPanel control, I want to add "Select" GridButtonColumn to the parent grid, so that clicking on it can return the primary key which I can use to populate the child grid with data.  Normally this would be a simple matter of hooking up the grids to a DataSet with two tables and a relationship between the tables, but in my case, everything needs to be done separately (i.e. the child grid's data isn't retrieved from the DB until the user actually clicks an item in the parent grid.

So... in the ParentChildGridPanel control, I want to add the "Select" column to the parent grid.  My "ParentChildGridPanel" user control exposes two properties to get at the underlying "GridPanel" user controls nested in it... these properties are called "ParentGridPanel" and "ChildGridPanel".  Each GridPanel control exposes a property called "ActiveGrid" which exposes the underlying RadGrid.

I'm using the following code in the Page_Init handler:

        protected void Page_Init(object sender, EventArgs e) 
        { 
            // Attach the parent grid's SelectedIndexChanged event 
            ParentGridPanel.ActiveGrid.SelectedIndexChanged += new EventHandler(ParentGrid_SelectedIndexChanged); 
 
            // Create the new GridButtonColumn to attach to the parent grid 
            GridButtonColumn GBC = new GridButtonColumn(); 
            GBC.CommandName = "Select"
            GBC.UniqueName = "Details"
            GBC.Text = "Details"
 
            // Attach the new column 
            this.ParentGridPanel.ActiveGrid.Columns.Add(GBC); 
        } 

I have created a delegate called "DrillDownSelected", along with custom event arguments, to be used in the ParentGrid_SelectedIndexChanged event handler (referenced in the above code).  The purpose is to raise an event back to the main page, alerting the page that the user has selected an item in the parent grid and that it needs to retrieve the data for the child grid.  The code is as follows:
        void ParentGrid_SelectedIndexChanged(object sender, EventArgs e) 
        { 
            RadGrid ParentGrid = (RadGrid)sender; 
 
            // Find the item selected by the user and get the value of the data key value field 
            object x = ParentGrid.SelectedItems[0].OwnerTableView.DataKeyValues[ParentGrid.SelectedItems[0].ItemIndex]["PRIMARY_KEY"]; 
 
            // Build the custom argument to send back to the main page 
            DrillDownEventArgs customArgs = new DrillDownEventArgs(); 
            customArgs.UniqueParentID = Int32.Parse(x.ToString()); 
 
            // Alert the main page that the user has clicked an item in the ParentGrid 
            if (DrillDownSelected != null
            { 
                this.DrillDownSelected(this, customArgs); 
            } 
        } 

All of this works exactly as I want it to.  The problem arises when the user click on the "Details" link of the Select column that was added in the Init event handler... I end up getting an additional "Details" column every time, but I lose the content of the column itself.  I know it's a Details column because I can look at the UniqueName property.  In other words, on postback I get the new Details column, and then a blank "old" Details column to the right.  On the next postback, the new Details column, and then 2 blank "old" Details columns to the right... next postback, Details column, 3 blank columns, etc.

I'm not sure why this is happening, although I suspect it's a ViewState issue.  To remedy the problem, I've added the following code to my ParentChildGridPanel's "Page_Load" event handler to remove the unwanted column each time:
        protected void Page_Load(object sender, EventArgs e) 
        { 
            if (Page.IsPostBack) 
            { 
                this.ParentGridPanel.ActiveGrid.Columns.RemoveAt(this.ParentGridPanel.ActiveGrid.Columns.Count - 1); 
            } 
        } 
 

This works just fine, although it seems very "hacky" to me to have to do this.  I'll admit that I don't completely understand every detail of all of the columns collections on a RadGrid (RadGrid.Columns, RadGrid.MasterTableView.Columns, RadGrid.MasterTableView.RenderColumns) and when to use one over the other, so perhaps I'm just going about this the wrong way.

What is the "best practice" way to achieve my original goal?

Thank you.

3 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 29 Jul 2009, 02:13 PM
Hi Golem,

Indeed the grid columns are saved in ViewState by default and that is why you have such problems. When the grid is declared on the page the proper place to add grid columns is OnLoad. You should add the column immediately before access/set any column properties. You can control all these using EnableColumnsViewState property  of GridTableView (by default is true).

More info about this you can find in the description of this demo:
http://demos.telerik.com/aspnet-ajax/grid/examples/programming/groupby/defaultcs.aspx

Greetings,
Vlad
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Golem
Top achievements
Rank 1
answered on 29 Jul 2009, 03:42 PM
Thank you for your reply, Vlad.  I stumbled across the ViewState issue about an hour before reading your reply, since I had to disable ViewState for my ParentChildPanel user control.  When I did this, of course, I no longer needed to remove the Details column during the Page_Load event handler.

I do have one question about your suggestion of creating the GridBoundColumn objects in the Page_Load however... How do I then wire up the command so that it correctly triggers the SelectedIndexChanged event?  By creating the column in the Page_Init, and setting the CommandName property to "Select", something happens to automatically connect the command to the SelectedIndexChanged event.  If I create the column in the Page_Load, it happens too late in the page lifecycle to have this happen.  How do I wire it up manually?

0
Sebastian
Telerik team
answered on 03 Aug 2009, 10:57 AM
Hello Golem,

If you follow precisely the conceprts for runtime grid creation on PageLoad explained in detail in this help topic, the viewstate and lifecycle of the control should remain intact. Please verify that and let us know if we can be of a further assistance.

Regards,
Sebastian
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
Tags
Grid
Asked by
Golem
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Golem
Top achievements
Rank 1
Sebastian
Telerik team
Share this question
or