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

Hyperlinks not retained on postback

11 Answers 411 Views
Grid
This is a migrated thread and some comments may be shown as answers.
unnati
Top achievements
Rank 1
unnati asked on 30 May 2011, 02:23 PM
Hi Telerik Team

I have a RadGrid which is fetching data from a DataTable and uses OnNeedDataSource event for databinding. The columns are generated dynamically at runtime based on data from DataTable.
One of the columns of the RadGrid requires a hyperlink to the text displayed. I achieved this in ItemDataBound event where in I added a Hyperlink control to the cell.
This works fine.
But when the page postback occurs due to a change in server-side drop-down outside the Telerik RadGrid, the hyperlinks are not retained.
After page postback occurs, the hyperlinks are gone and data is displayed as plain text instead of hyperlinks.

One of the resolutions I tried is to ReBind() the RadGrid in PreRender event. But after doing that, Export To Excel functionality gives a problem. It gives excel file with an extra cell wherein where in I get custom-added URLS and images which is not expected. I also added IgnorePaging=true and ExportOnlyData=true for the same.

Please provide a resolution for the issue of retaining hyperlinks without affecting the functionality of Export to Excel.

11 Answers, 1 is accepted

Sort by
0
Princy
Top achievements
Rank 2
answered on 30 May 2011, 03:10 PM
Hello Unnati,

Creating columns in the Page_Load event handler does not work for template columns. For the controls inside a template to persist their ViewState, the grid must be generated completely in the code-behind using the Page_Init event.

When generating a grid in the Page_Init event handler, grid columns should be added to the Columns collection of the MasterTableView after their attributes are set. No ViewState  is required for grid structure to be persisted as it is recreated on each page initialization.

Check out the following help article for more on this.
Programmatic creation.

Thanks,
Princy.
0
unnati
Top achievements
Rank 1
answered on 31 May 2011, 08:46 AM
Hello Telerik Team,

In my RadGrid I am not generating columns using template columns. I am generating RadGrid columns from a DataTable dynamically.
The code is shown below:
<div class="telerikwrapper">
                    <telerik:RadGrid AllowPaging="True" CellSpacing="0" GridLines="None" Height="100%"
                       ID="RadGrid1" OnItemCommand="RadGrid1ItemCommand"
                        OnNeedDataSource="RadGrid1GridNeedDataSource" OnItemCreated="RadGrid1ItemCreated"
                        OnItemDataBound="RadGrid1ItemDataBound" OnPreRender="RadGrid1PreRender"
                        runat="server"  Width="100%" AllowSorting="False">
                       <MasterTableView CommandItemDisplay="Top" >
                            <CommandItemTemplate>
                                <asp:ImageButton ID="ExportToExcel"  runat="server" CssClass="DownloadExcel" ImageUrl="/_layouts/RIOCRG/Images/exptoExcel.png"
                                    ToolTip="Export report snapshot to Excel" CommandName="ExportToExcel"></asp:ImageButton>                     
                                <asp:LinkButton ID="btnShowAllRecords" CssClass="DownloadExcel" OnClick="BtnShowAllRecordsClick"
                                    Visible="false" runat="server" Text="Show All" />
                            </CommandItemTemplate>
                             
                        </MasterTableView>
                    </telerik:RadGrid>
                     
                  
 
 
                </div>
       
        protected void Page_Load(object sender, EventArgs e)
        {
            
 
        }
 
       
        protected void RadGrid1NeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
 
            RadGrid RadGrid1 = source as RadGrid;
            if (RadGrid1 == null) return;
 
            
 
                   try
                   {
                       if (!IsPostBack)
                       {
                           
                            
 
                           DataTable formattedTable = GetDataTable();
 
                            
 
                           if (ViewState["Data"] == null)
                           {
                                
                               ViewState["Data"] = formattedTable;
                           }
                       }
                       else
                       {
                           formattedTable = ViewState["Data"] as DataTable;
                       }
 
                       if (formattedTable.Rows.Count != 0)
                       {
                           RadGrid1.DataSource = formattedTable;
                       }
                       else
                       {
                           RadGrid1.DataSource = new Object[0];
                       }
                   }
                   catch (Exception ex)
                   {
                       Logger.Write(ex);
                   }
                
        }
 
       
        protected DataTable GetDataTable()
        {
            //Retrieving data from database
            
        }
 
        
        protected void RadGrid1ItemCommand(object sender, GridCommandEventArgs e)
        {
            RadGrid grid = sender as RadGrid;
            if (e.CommandName == RadGrid.ExportToExcelCommandName)
            {
                if (grid != null)
                {
                    grid.ExportSettings.IgnorePaging = true;
                    grid.ExportSettings.ExportOnlyData = true;
                }
            }
        }
 
       
        protected void RadGrid1PreRender(object sender, EventArgs e)
        {
 
           RadGrid1.Rebind();
           
            for (int rowIndex = 0; rowIndex < RadGrid1.Items.Count; rowIndex++)
            {
                for (int j = 1; j < RadGrid1.Items[rowIndex].Cells.Count; j++)
                {
                    RadGrid1.Items[rowIndex].Cells[j].Style["border-bottom"] = "1px solid #ccc";
                    RadGrid1.Items[rowIndex].Cells[j].Style["font-weight"] = "bold"
                }   
            }
        }
 
       
        protected void RadGrid1ItemDataBound(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridDataItem)
            {
 
                GridDataItem dataItem = e.Item as GridDataItem;
                GridTableCell cell = (GridTableCell)dataItem["SampleColumn"];
                HyperLink hlControl = new HyperLink();
                hlControl.Text = cell.Text;
                hlControl.NavigateUrl =  "www.google.com" ;              
                dataItem["SampleColumn"].Controls.Add(hlControl);
 
            }          
        }
 
      
        protected void BtnShowAllRecordsClick(object sender, EventArgs e)
        {
            RadGrid1.AllowPaging = !RadGrid1.AllowPaging;
            RadGrid1.Rebind();
        }
 
         
       
    }
}
0
Accepted
Princy
Top achievements
Rank 2
answered on 31 May 2011, 11:36 AM
Hello Unnati,

In general the proper place for adding controls to the grid items is in ItemCreated. But in the case of adding controls to the cells of GridBoundColumn,you cannot use ItemCreated only, but a combination of ItemCreated and ItemDataBound. This is due to the fact that the control created in ItemCreated will be erased when data-binding this control. Also, if you create the control in ItemDataBound when the controls are created from ViewState, the grid will not raise ItemDataBound, and the control will not be created and would not raise postback events. The solution for such cases is to create the control in ItemDataBound and recreate this control if needed on ItemCreated for subsequent postbacks. Here is the sample code that I tried which worked as expected.

C#:
protected void RadGrid2_ItemCreated(object sender, GridItemEventArgs e)
 {
   if (e.Item is GridDataItem)
   {
     GridDataItem dataItem = (GridDataItem)e.Item;
     HyperLink hlControl  = new HyperLink();
  hlControl .Text = RadGrid2.MasterTableView.DataKeyValues[e.Item.ItemIndex]["SampleColumn"].ToString();
     hlControl .NavigateUrl = "www.google.com";
     dataItem["SampleColumn"].Controls.Add(hlControl );
   }
  }
protected void RadGrid2_ItemDataBound(object sender, GridItemEventArgs e)
{
   if (e.Item is GridDataItem)
   {
            GridDataItem dataitem = (GridDataItem)e.Item;
            HyperLink hlControl  = new HyperLink();
         hlControl .Text = cell.Text;
            hlControl .NavigateUrl = "www.google.com";
           dataitem["SampleColumn"].Controls.Add(hlControl );
      }
 }


Thanks,
Princy.
0
unnati
Top achievements
Rank 1
answered on 31 May 2011, 02:43 PM
0
unnati
Top achievements
Rank 1
answered on 01 Jun 2011, 07:34 AM



                            
                      
0
unnati
Top achievements
Rank 1
answered on 01 Jun 2011, 08:29 AM
Hello Telerik Team,

I implemented the sample code posted earlier.
But it seems to throw 'Object reference not set to an instance of an object' at the following line of code

RadGrid2.MasterTableView.DataKeyValues[e.Item.ItemIndex]["Tactic"].ToString();


Please provide resolution for the issue.
0
Accepted
Princy
Top achievements
Rank 2
answered on 01 Jun 2011, 09:24 AM
Hello Unnati,

I suppose the issue is because of not setting DataKeyNames.

aspx:
<MasterTableView DataKeyNames="Tactic" >
</MasterTableView>

Thanks,
Princy.
0
unnati
Top achievements
Rank 1
answered on 01 Jun 2011, 09:58 AM
Hello Telerik Team,

Thanks for the response. The resolution given worked for me.
0
unnati
Top achievements
Rank 1
answered on 08 Jun 2011, 05:29 PM
Hello team,

The given solution worked for a normal gridview.

Now, I have a hierarchical gridview of 4 level and I want three columns of gridview to be hyperlinked. I tried to implement it in the similar manner, but in 'RadGrid2_ItemCreated' function, I am getting error in
RadGrid2.MasterTableView.DataKeyValues[e.Item.ItemIndex]["SampleColumn"].ToString()
Error: Index was out of range. Must be non-negative and less than the size of the collection.
I am getting this error for index of DataKeyValues.
I have provided DataKeyNames for all three columns as MasterTableView attribute.

Also, I am not sure whether it will work all four gridviews.

I have followed the approach given in following link to create hierarchical gridview
http://demos.telerik.com/aspnet-ajax/grid/examples/programming/detailtabledatabind/defaultcs.aspx

Can you please suggest how to retain hyperlinks for hierarchical gridview?
0
Daniel
Telerik team
answered on 14 Jun 2011, 01:13 PM
Hello Unnati,

If you need to access value from a column that resides in a detail table you will have to modify the code this way:
protected void RadGrid2_ItemCreated(object sender, GridItemEventArgs e)
{
        ...
        hlControl.Text = dataItem.GetDataKeyValue("ColumnName").ToString();
        ...
}

Of course you have to add the corresponding datakey name to the collection:
....
    <DetailTables>
        <telerik:GridTableView DataKeyNames="ColumnName">
        </telerik:GridTableView>
    </DetailTables>
   ....
</MasterTableView>

Furthermore you can add your own names to each tableview if you need to be able to distinguish the detail tables in code-behind.
<telerik:GridTableView Name="DetailLevel1" ....>
 ....

Then you can check the table name as shown below:
protected void RadGrid2_ItemCreated(object sender, GridItemEventArgs e)
{
    if (e.Item.OwnerTableView.Name == "DetailLevel1" && .....)
    {
       ....

Regards,
Daniel
the Telerik team

Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.

0
unnati
Top achievements
Rank 1
answered on 16 Jun 2011, 11:42 AM
Thanx Daniel, that worked fine for me..:)
Tags
Grid
Asked by
unnati
Top achievements
Rank 1
Answers by
Princy
Top achievements
Rank 2
unnati
Top achievements
Rank 1
Daniel
Telerik team
Share this question
or