ASP.NET GridView RowCommand not firing
Hi,
I'm developing a SiteFinity 4 custom module in which I have an ASP.NET GridView which has a delete button and I'm trying to fire the OnRowDataBind and OnRowCommand events but it wont work.
My view template:My template class:
<%@ Control Language="C#" %><%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %><h1> Job Applications</h1><div style="padding: 20px;"> <asp:Literal ID="litTest" runat="server" /> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" ForeColor="#284775" /> <Columns> <asp:TemplateField HeaderText="First Name"> <ItemTemplate> <%# Eval("FirstName") %> </ItemTemplate> <ItemStyle Width="150px" /> </asp:TemplateField> <asp:TemplateField HeaderText="Last Name"> <ItemTemplate> <%# Eval("LastName") %> </ItemTemplate> <ItemStyle Width="150px" /> </asp:TemplateField> <asp:TemplateField HeaderText="Phone"> <ItemTemplate> <%# Eval("Phone") %> </ItemTemplate> <ItemStyle Width="150px" /> </asp:TemplateField> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkDelete" runat="server" CommandName="cmdDelete" Text="Delete" /> </ItemTemplate> </asp:TemplateField> </Columns> <EditRowStyle BackColor="#999999" /> <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" /> <RowStyle BackColor="#F7F6F3" ForeColor="#333333" /> <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" /> <SortedAscendingCellStyle BackColor="#E9E7E2" /> <SortedAscendingHeaderStyle BackColor="#506C8C" /> <SortedDescendingCellStyle BackColor="#FFFDF8" /> <SortedDescendingHeaderStyle BackColor="#6F8DAE" /></asp:GridView></div>
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telerik.Sitefinity.Modules.Pages.Web.UI;using Telerik.Sitefinity.Web.UI;using Telerik.Web.UI;using Telerik.Sitefinity.Libraries.Model;using Telerik.Sitefinity.Model;using System.Web.UI.WebControls;using Telerik.Sitefinity;using System.Web;namespace Jobs.PublicControls [RequireScriptManager] public class BackendOverviewControl : SimpleView protected override string LayoutTemplateName get return this.layoutTemplateName; protected virtual GridView JobsGrid get return base.Container.GetControl<GridView>("GridView1", true); protected virtual Literal litTest get return base.Container.GetControl<Literal>("litTest", true); protected override void OnInit(EventArgs e) JobsGrid.RowDataBound += new GridViewRowEventHandler(JobsGrid_RowDataBound); JobsGrid.RowCommand += new GridViewCommandEventHandler(JobsGrid_RowCommand); base.OnInit(e); protected override void InitializeControls(GenericContainer controlContainer) protected void JobsGrid_RowCommand(object sender, GridViewCommandEventArgs e) if (e.CommandName == "cmdDelete") litTest.Text = "You selected : " + e.CommandArgument.ToString(); /*using (var sf = App.Prepare().SetTransactionName("JobApplicationTransaction").WorkWith()) Document doc = sf.Documents().Where(d => d.Id.ToString() == e.CommandArgument.ToString()).Get().Single(); if (doc != null) litTest.Text = doc.Title; */ protected void JobsGrid_RowDataBound(object sender, GridViewRowEventArgs e) if (e.Row.RowType == DataControlRowType.DataRow) Document doc = (Document)e.Row.DataItem; if (doc != null) LinkButton lnkDelete = (LinkButton)e.Row.FindControl("lnkDelete"); lnkDelete.CommandArgument = doc.Id.ToString(); protected override void OnPreRender(EventArgs e) var module = new Jobs_Module(); JobsGrid.DataSource = module.getDocuments(); JobsGrid.DataBind(); base.OnPreRender(e); private string layoutTemplateName = "Jobs.Resources.Views.BackendOverviewTemplate.ascx"; Hello Raihan,
If you subscribe for GridView.RowDataBound inside InitializeControls the events are fired.
Regards,
Ivan Dimitrov
the Telerik team
Hi Ivan,
I moved the event handlers inside InitializeControls but the events are NOT fired. Please note this is an ASP.NET GridView control not RadGrid!
I placed a breakpoint on the RowCommand event handler to check if the event is fired or not.
protected override void InitializeControls(GenericContainer controlContainer) JobsGrid.RowDataBound += new GridViewRowEventHandler(JobsGrid_RowDataBound); JobsGrid.RowCommand += new GridViewCommandEventHandler(JobsGrid_RowCommand);Hi Raihan,
If you subscribe for these events inside CreateChildControls there should not be a problem
protected override void CreateChildControls()
base.CreateChildControls();
// add data source
GridView.RowCommand += new GridViewCommandEventHandler(GridView_RowCommand);
GridView.DataBind();
If you want you can create your own base class that inherits from CompositeControl and use it
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web.UI.WebControls;using System.Web.UI;using Telerik.Sitefinity.Web.UI;using Telerik.Sitefinity.Web.UI.Templates;using Telerik.Sitefinity.Abstractions;using Telerik.Sitefinity.Configuration;using Telerik.Sitefinity.Web.Configuration;using Telerik.Sitefinity.Modules.Pages;namespace Telerik.Sitefinity.Samples public class CompositeControlCustom : CompositeControl, INamingContainer protected override void CreateChildControls() Controls.Clear(); if (Grid != null) var pm = PageManager.GetManager(); Grid.DataSource = pm.GetPageNodes(); Grid.RowCommand += new GridViewCommandEventHandler(Grid_RowCommand); this.Container.Controls.Add(Grid); this.Controls.Add(Container); Grid.DataBind(); void Grid_RowCommand(object sender, GridViewCommandEventArgs e) public override void DataBind() CreateChildControls(); ChildControlsCreated = true; base.DataBind(); public virtual ITemplate Template get if (this.templateValue == null) var tempInfo = new TemplateInfo() TemplatePath = this.LayoutTemplatePath, TemplateName = this.LayoutTemplateName, TemplateResourceInfo = this.ResourcesAssemblyInfo, ControlType = this.GetType(), Key = TemplateKey ; this.templateValue = ControlUtilities.GetTemplate(tempInfo); return this.templateValue; set this.templateValue = value; internal protected virtual GenericContainer Container get if (this.container == null) this.container = this.CreateContainer(this.Template); return this.container; protected virtual Type ResourcesAssemblyInfo get var type = this.GetType(); if (type.Assembly == typeof(ObjectFactory).Assembly) return Config.Get<ControlsConfig>().ResourcesAssemblyInfo; return type; protected internal virtual GenericContainer CreateContainer(ITemplate template) GenericContainer container = new GenericContainer(); template.InstantiateIn(container); return container; public virtual string TemplateKey get; set; protected virtual GridView Grid get return this.Container.GetControl<GridView>("GridView1", true, TraverseMethod.BreadthFirst); private ITemplate templateValue; private GenericContainer container; public virtual string LayoutTemplatePath get; set; public virtual string LayoutTemplateName get; set; Why not just add the argument:"
OnRowCommand="JobsGrid_RowCommand
to the gridview? That should solve the problem.
Or am I missing something here?
Hi Michiel,
I prefer to subscribe for the events using CreateChildControls.
1. The class is related to the template with LayoutTemplatePath property, so this is not just a user control
2. If someone decide to override the event they can do it in CreateChildControls ( this is useful when you want to distribute an assembly and someone else to extend it if needed).
Regards,
Ivan Dimitrov
the Telerik team