简体   繁体   中英

ASP.NET LinkButton not invoking 'OnCommand' event

I have a ListView nested inside the column of a GridView, which looks something like this:

<asp:panel id="myPanel" Runat="server" EnableViewState="False">
    <asp:GridView id="myDescription" AutoGenerateColumns="False" Width="100%" runat="server"
         OnRowCommand="my_RowCommand"  OnRowDataBound="GetDataForListView" EnableViewState="False">
        <Columns>
            <asp:BoundField DataField="id" HeaderText="ID">
                <HeaderStyle HorizontalAlign="Center"></HeaderStyle>
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
            </asp:BoundField>
            <asp:BoundField DataField="data1" HeaderText="Thing 1">
                <HeaderStyle   HorizontalAlign="Center"></HeaderStyle>
                <ItemStyle   HorizontalAlign="Center"></ItemStyle>
            </asp:BoundField>
            <asp:BoundField DataField="data2" HeaderText="Thing2">
                <HeaderStyle   HorizontalAlign="Center"></HeaderStyle>
                <ItemStyle   HorizontalAlign="Center"></ItemStyle>
            </asp:BoundField>
            <asp:BoundField DataField="data3" HeaderText="Thing3">
                <HeaderStyle   HorizontalAlign="Center"></HeaderStyle>
                <ItemStyle   HorizontalAlign="Center"></ItemStyle>
            </asp:BoundField>
            <asp:TemplateField SortExpression="id">
                <ItemTemplate> 
                    <asp:HyperLink id="hlView"  runat="server"  NavigateUrl="...">View</asp:HyperLink>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Column to contain my list of things">
                <HeaderStyle HorizontalAlign="Center"></HeaderStyle>
                <ItemStyle HorizontalAlign="Center"></ItemStyle>
                <ItemTemplate>
                    <% /* This is my list view: */ %>
                    <asp:ListView ID="myListView" runat="server" OnItemCommand="DoSomething" EnableViewState="False">
                        <ItemTemplate>
                            <asp:LinkButton ID="lbAttachment" Runat="Server" Text='<%# Eval("FILE_NAME") %>'
                                CommandName='<%# Eval("ROW_NUM") %>' CausesValidation="False" > 
                            </asp:LinkButton><br/>
                        </ItemTemplate>
                    </asp:ListView>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</asp:panel>

The data is successfully binding, but the OnCommand event is not being fired on clicking the LinkButton (nor is any other event for the LinkButton, such as an OnClick event).

The rendered HTML for the link button shows that on clicking it, the page is performing a postback: javascript:__doPostBack('...','')

This means it is going back into my 'Page_Load' and refreshing the contents of the page - the grid view is binded here.

I can stop it from performing a postback by adding this attribute to the LinkButton:

OnClientClick="return false;"

But this only stops the postback from occurring, the OnCommand event still doesn't fire.

Any ideas?

The event signature in the code-behind is:

protected void DoSomething(object sender, CommandEventArgs e) { ... }

I have also tried using an OnItemCommand event on the ListView control with this event signature, but similarly the event is not invoked:

protected void DoSomething(object sender, ListViewCommandEventArgs e)

The OnRowdataBound event on the parent GridView is successfully invoked, it's only the nested ListView that fails to invoke its event.

The code I have shown is for the 2nd GridView on the page, there is another one too, and it is this one which gets binded on the Page_Load event. The Page Load event has a sequence of events as follows, where the 1st GridView (which we'll call GridView1) is bound:

Page_Load

Data for GridView is retrieved from database

  • Data is assigned to a 'DataView' object and assigned to the GridView1 DataSource property.
  • GridView1.DataBind() is invoked
  • Miscellaneous conditional logic which removes certain columns from GridView1
  • An OnClick attribute is added to each row.

So actually, the Page_Load binds the first GridView. The 2nd GridView is the one which contains the ListView which I am having a problem with. This 2nd GridView (the code of which is at the top of the post) is populated on the 'OnRowCommand' event of the 1st GridView, and has a sequence like this:

GetDataForListView

Get data from database

  • Assign the DataSet containing the data to the DataSource property of the 2nd GridView
  • Call the DataBind() method

Then, as you can see from the code I posted at the top, I have the OnRowDataBound event which fails to invoke its event in the code-behind.

Ciaran, I replicated the whole scenario and found out the below issue.

Issue: When any event related to either the GridView2 or ListView or the LinkButton is being fired it first hits the Page_load function . In the Page_load function you are not data binding GridView2 and the ListView so apparently they almost vanish and so the Event will not be fired.

Possible Fix:

  1. You need to bind the GridView2 in the Page_load function in order fire those related events and the same goes with the ListView Too.

  2. This fix is a very big one. I am not sure if you could try this.

a. If you are binding the GridView2 depending on the condition generated by the GridView1 click then store those parameters in some hidden field.

b. Have a function named LoadGridView2(parameters) where you bind the GridView2 and the ListView depending on the parameters passed and call this function in the Page_Load function each every time a PostBack is done and pass the stored parameters in the hidden field to the LoadGridView2(parameters)

c. By doing above you can bind the GridView2 according the GirdView1 Click condition and make the GridView2 and ListView available in the PostBack too. So now the event could be fired.

Let me know in case of any queries.

LinkButton has OnCommand , ListVIew has OnItemCommand . So the name isn't correct. OnCommand only fires if the LinkButton has a CommandName set. And also, the repeater may swallow the button's command argument. Certain controls do that because of the way events bubble up to the UI.

 <asp:LinkButton ID="linkButton" Runat="Server" OnCommand="DoSomething"  
    CommandName="DoSomething"
    CommandArgument='<%# Eval("ROW_NUM") %>' Text='<%# Eval("FILE_NAME") %>'> 
    </asp:LinkButton>

Or Try adding:

<asp:ListView .. OnItemCommand=".." />

And then do:

void DoSomething(Object Sender, ListViewCommandEventArgs e) {        

      // Do something
   } 

Your button would still need to set a command name like:

 <asp:LinkButton .. CommandName="DoSomething" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM