GridView RowCommand Not Firing

A

AG

I have a gridview that I bind to a List(of Type) at runtime.
Not using a datasource control.
The gridview has a template column with an imagebutton whose commandname is
set to 'Delete'.
The footer template has an commandbutton with the commandname set to
'Insert'.
Both buttons cause postback, however the RowCommand event does not fire.

How can I get the rowcommand to fire?

TIA
 
P

PeterKellner

I have a gridview that I bind to a List(of Type) at runtime.
Not using a datasource control.
The gridview has a template column with an imagebutton whose commandname is
set to 'Delete'.
The footer template has an commandbutton with the commandname set to
'Insert'.
Both buttons cause postback, however the RowCommand event does not fire.

How can I get the rowcommand to fire?

TIA

Here is some sample code that does work with the linkbutton.

<asp:GridView ID="GridViewAvailablePictures" runat="server"
AutoGenerateColumns="False" DataKeyNames="id"
DataSourceID="ObjectDataSourceAvailablePictures"
OnRowCommand="GridViewAvailablePictures_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkAssignButton" runat="server"
CommandName="Assign"
Text="Assign Picture To Session" Visible="true">
</asp:LinkButton>
<br />
<asp:Label ID="Label1" runat="server" Text='<%#
Bind("FileName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="id" InsertVisible="False"
SortExpression="id">
<ItemTemplate>
<asp:Image ID="Image1" runat="server"
ImageUrl='<%# "~/DisplayImage.ashx?sizex=120&pictureid=" + Eval("id")
%>' />

</ItemTemplate>
</asp:TemplateField>

<asp:BoundField DataField="Description"
HeaderText="Description" SortExpression="Description"
Visible="False" />

</Columns>
</asp:GridView>
Peter Kellner
http://peterkellner.net
 
A

AG

Peter,

Thanks for the quick reply.
If I use a datasource control as in your sample, the rowcommand event will
fire.
I am not using a datasource control, but setting the datasource of the
gridview to a List(of Type) at runtime.
 
S

Steven Cheng[MSFT]

Hello AG,

Based on my experience, no matter we bind GridView through
DataSourceControl or normal data object collection, the RowCommand and
other Row based postback event(RowUpdating, RowEditing .... ) should work.
For your scenario, I think it is likely a page or control specific issue.
Here is a smiple test page with a GridView that bind to a custom class
Array, and I use a submit button and image button in the TemplateColumn,
also a submit button(with CommandName="Insert") in the footer template, all
these buttons can trigger the RowXXX event correctly. I've included the
complete page's aspx and codebehind source below, you can test it on your
side to see whether it works.



==============aspx===============
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false" OnRowCommand="GridView1_RowCommand"
OnRowDeleting="GridView1_RowDeleting" OnRowEditing="GridView1_RowEditing"
ShowFooter="True">
<Columns>
<asp:BoundField DataField="CategoryID"
HeaderText="CategoryID" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" />
<asp:BoundField DataField="Description"
HeaderText="Description" />
<asp:TemplateField HeaderText="TemplateField">
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" Text="Edit"
CommandName="Edit" />
<asp:ImageButton ID="imgBtn" runat="server"
ImageUrl="http://wcf.netfx3.com/Themes/default/images/logo.gif"
CommandName="Edit" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnInsert" runat="server" Text="Insert"
CommandName="Insert" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>

</div>
</form>
</body>
============================

=========code behind==============
public partial class dataaccess_CustomVOGridView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();

}

}

private void BindGrid()
{
CategoryVO[] categories = new CategoryVO[10];

for (int i = 0; i < categories.Length; i++)
{
CategoryVO vo = new CategoryVO();
vo.CategoryID = i + 1;
vo.CategoryName = "Category_" + vo.CategoryID;
vo.Description = "Description of " + vo.CategoryName;

categories = vo;
}

GridView1.DataSource = categories;
GridView1.DataBind();
}
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{

Response.Write("<br/>GridView1_RowCommand: " + e.CommandName);


}
protected void GridView1_RowDeleting(object sender,
GridViewDeleteEventArgs e)
{
Response.Write("<br/>GridView1_RowDeleting " + e.RowIndex);
}
protected void GridView1_RowEditing(object sender,
GridViewEditEventArgs e)
{
Response.Write("<br/>GridView1_RowEditing " + e.NewEditIndex);
}
}
==========================

=========custom class===============
public class CategoryVO
{
private int _id;
private string _name;
private string _description;


public CategoryVO()
{

}

public CategoryVO(int id, string name, string description)
{
_id = id;
_name = name;
_description = description;
}


public int CategoryID
{
get { return _id; }
set { _id = value; }
}

public string CategoryName
{
get { return _name; }
set { _name = value; }
}

public string Description
{
get { return _description; }
set { _description = value; }
}


}
=================================

Please feel free to let me know if you have any further questions or new
finding.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

AG

Steven,

Thanks for the reply.
I have tracked down my problem.
It has to do with master pages.

In a normal page, your sample works fine.

I put it in a content control on a content page.
The RowCommand for the template column did not fire.
It DID fire for the delete column, which is NOT a template column.
This is what was confusing me.

Bottom line is that the ContentPlaceHolder of the masterpage had viewstate
turned off.
Once I turned it back on, all the events fired.

On another note.
I like the idea of using the footer of the gridview to add a new record.
However, if there is no data, the gridview does not render at all.
Is there any way to render the header and footer if there is no data for the
gridview?

--

AG
Email: discuss at adhdata dot com



Steven Cheng said:
Hello AG,

Based on my experience, no matter we bind GridView through
DataSourceControl or normal data object collection, the RowCommand and
other Row based postback event(RowUpdating, RowEditing .... ) should work.
For your scenario, I think it is likely a page or control specific issue.
Here is a smiple test page with a GridView that bind to a custom class
Array, and I use a submit button and image button in the TemplateColumn,
also a submit button(with CommandName="Insert") in the footer template,
all
these buttons can trigger the RowXXX event correctly. I've included the
complete page's aspx and codebehind source below, you can test it on your
side to see whether it works.



==============aspx===============
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false" OnRowCommand="GridView1_RowCommand"
OnRowDeleting="GridView1_RowDeleting" OnRowEditing="GridView1_RowEditing"
ShowFooter="True">
<Columns>
<asp:BoundField DataField="CategoryID"
HeaderText="CategoryID" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" />
<asp:BoundField DataField="Description"
HeaderText="Description" />
<asp:TemplateField HeaderText="TemplateField">
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" Text="Edit"
CommandName="Edit" />
<asp:ImageButton ID="imgBtn" runat="server"
ImageUrl="http://wcf.netfx3.com/Themes/default/images/logo.gif"
CommandName="Edit" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnInsert" runat="server" Text="Insert"
CommandName="Insert" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>

</div>
</form>
</body>
============================

=========code behind==============
public partial class dataaccess_CustomVOGridView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();

}

}

private void BindGrid()
{
CategoryVO[] categories = new CategoryVO[10];

for (int i = 0; i < categories.Length; i++)
{
CategoryVO vo = new CategoryVO();
vo.CategoryID = i + 1;
vo.CategoryName = "Category_" + vo.CategoryID;
vo.Description = "Description of " + vo.CategoryName;

categories = vo;
}

GridView1.DataSource = categories;
GridView1.DataBind();
}
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{

Response.Write("<br/>GridView1_RowCommand: " + e.CommandName);


}
protected void GridView1_RowDeleting(object sender,
GridViewDeleteEventArgs e)
{
Response.Write("<br/>GridView1_RowDeleting " + e.RowIndex);
}
protected void GridView1_RowEditing(object sender,
GridViewEditEventArgs e)
{
Response.Write("<br/>GridView1_RowEditing " + e.NewEditIndex);
}
}
==========================

=========custom class===============
public class CategoryVO
{
private int _id;
private string _name;
private string _description;


public CategoryVO()
{

}

public CategoryVO(int id, string name, string description)
{
_id = id;
_name = name;
_description = description;
}


public int CategoryID
{
get { return _id; }
set { _id = value; }
}

public string CategoryName
{
get { return _name; }
set { _name = value; }
}

public string Description
{
get { return _description; }
set { _description = value; }
}


}
=================================

Please feel free to let me know if you have any further questions or new
finding.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no
rights.
 
S

Steven Cheng[MSFT]

Thanks for your reply AG,

Based on your further description, I'm getting abit closer to the problem
your encountered. And I think the main cause here should be your
ContentPlaceHolder's ViewState is disabled rather than master page. As
for Template databound control such as GridView, DataGrid, after
databinding, they'll store the bound data into ViewState so that we do not
need to rebind the data in seqentual postback. However, when you disable
the ViewState of them or their container control, the bound data won't be
persisted after databinding, therefore we need to perform databinding on
each page request(no matter the intial request or postback).

I've modified my last test example and put the content page in a
ContentPlaceHolder within a master page and set its EnableViewState to
"false". And as long as I bind data to the GridView in each page request,
all the postback commands (our custom button in templateField or built-in
button field ) can work as expected. My modified page codebehind is as
below:

==================
protected void Page_Load(object sender, EventArgs e)
{

BindGrid();

}
====================

All the other code remains the same. So is your page also rebinding the
data to the GridView in each request? You can test the same behavior
through the my page or your modifeid version to see whether it works.

If there is anything unclear or any other questions , please feel free to
let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

AG

Steven,

Thanks.
I had already confirmed your comments and have turned on viewstate for the
content placeholder. It being off was not intentional. Probably an
unintentional scroll of the mousewheel.
While I can get my project to do what I want now that I know how things
work, I do think that it should be considered a bug that the events don't
fire without viewstate for a template column, but DO fire for a
commandfield.

Please address the below item.

On another note.
I like the idea of using the footer of the gridview to add a new record.
However, if there is no data, the gridview does not render at all.
Is there any way to render the header and footer if there is no data for the
gridview?
 
S

Steven Cheng[MSFT]

Thanks for your reply AG,

As for the Footer, Header template for empty datasource case, I'm afraid so
far the GridView can not display any GridViewRow when there is no data
record in the DataSource since GridViewRow is generated based on DataSource
records. However, if you do want to provide a "insert item" interface even
when there is no data supplied in the DataSource, you can consider use the
"EmptyDataTemplate" to provide a insert user interface so that the user can
directly see the insert item panel when the datasource is empty(contains no
record). e.g.

====================

<asp:GridView ID="GridView1" runat="server" ...................>
...............................
<EmptyDataTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<asp:Button ID="btnInsert" runat="server" Text="Edit"
CommandName="Insert" />
</EmptyDataTemplate>
</asp:GridView>
====================

Please feel free to let me know if there is any thing else you wonder.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

AG

Thanks Steven,

I do know about the EmptyDataTemplate. It just seems like duplication of
work.
The 1.1 datagrid did show header/footer even if there were no data rows and
I was hoping that there was a way to duplicate that. I wll just have to use
another method.
 
S

Steven Cheng[MSFT]

Thanks for your reply AG,

Yes, the different implementation of GridView and DataGrid make us have to
handle the empty datasource scenario differently. Actually, this change is
also made according to some feedback from the community. Anyway, it seems
that we would prefer a more flexible interface of such a template databound
control. I think this is a good point that you can submit the request for
the ASP.NET product team to refer.

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Feedbac
kID=118879

Also, if you meet any new problem in the developing or if anything else we
can help, please feel free to post here.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

AG

Thanks Steven,

I would be happy to submit the request, but the link you supplied is for a
different issue:
The path '/WebSite/App_GlobalResources/' maps to a directory outside this
application, which is not supported.
 
S

Steven Cheng[MSFT]

Thanks for your quick reply AG,

yes, I incorrectly include the issue id in the former link. You can submit
through the root link of feedback page:

http://connect.microsoft.com/VisualStudio/feedback/

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

santosh.ha

Hi Steven,

I have read thru the reply chains I have one doubt when we are writing
differnt mehtod of editing and Deleting , why should we include the
method for onRowCommand in the grid declaration. I haev some similar
problem,

I Grid view with two buttonfields and have used OnRowCommand in the
gridview declaration. But during run time it thors an error as "The
GridView fired event RowEditing which wasn't handled."

Not sure why this is coming...should i given the implementation for
RoeEiditing and RowDeleting methods?

thanks,
Santosh
 
Joined
Aug 25, 2010
Messages
1
Reaction score
0
I like the idea of using the footer of the gridview to add a new record.
However, if there is no data, the gridview does not render at all.
Is there any way to render the header and footer if there is no data for the
gridview?

I know this thread is really old, but for anyone still looking for a way to display an Add New row in a GridView...

First, I don't use the footer to display an Add New row. Instead, I change the icon of the row edit button and hide the delete row button, during the GridView.RowDataBound event. Therefore, the GridView treats the Add New row as an ordinary row. Next, I append a record with NULL key values to the end of my data source. I suppose this would be a problem if I were using relationship objects to constrain the data, but I'm not.

This approach works with an ObjectDataSource control, like so:

Code:
protected void DataSource_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
    DataTable dt = (DataTable)e.ReturnValue;
    DataRow newRow = dt.NewRow();

    // If applicable, Set parent key values here...

    dt.Rows.Add(newRow);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top