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