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:
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:
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:
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.
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.
