2010-02-02 42 views
7

Tengo un LinkButton dentro de un GridView (a través de un TemplateField). No importa lo que intento, LinkButton no invocará su controlador de eventos. He intentado tanto:¿Por qué mi LinkButton dentro de un GridView no activa su evento OnClick?

  1. Un controlador de eventos tradicionales ("clic")
  2. Un OnRowCommand controlador de eventos a nivel GridView.

En ambos casos, he depurado y ni siquiera detecta el controlador de eventos.

Si muevo el LinkButton en la página (por lo que no está en GridView), funciona bien, así que sé que la sintaxis es la correcta.

Aquí es el método "tradicional":

<asp:TemplateField> 
    <ItemTemplate> 
    <asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" OnClick="CancelThis" runat="server" /> 
    </ItemTemplate> 
<asp:TemplateField> 

Lo que es interesante es si quito el método "CancelThis" del código detrás, se genera un error. Así que sé que conoce su controlador de eventos, porque lo busca cuando compila.

Aquí es el método RowCommand:

<asp:TemplateField> 
    <ItemTemplate> 
    <asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" CommandName="CancelThis" runat="server" /> 
    </ItemTemplate> 
<asp:TemplateField> 

En este caso, el GridView tiene:

OnRowCommand="GridView_RowCommand" 

Se postsback, pero nunca consejos a provocar el evento.

¿Alguna idea de lo que me falta aquí?

Respuesta

0

¿Viewstate está activado en su GridView? Esto me ha sorprendido en numerosas ocasiones.

10

¿Cómo vincula su GridView? ¿Estás usando un control de fuente de datos? Si está vinculando manualmente durante Page_Load, es posible que dado que la cuadrícula se está vinculando en cada viaje de ida y vuelta, el controlador de eventos no se está capturando correctamente. Si este es el caso, es posible que desee probar algo como:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if(!Page.IsPostBack) 
    { 
     //do binding 
    } 
} 

Se puede publicar código de enlace para ir con su margen de beneficio de la muestra?

Si realmente quiere forzar el problema, podría conectarse al evento RowDataBound en la cuadrícula, buscar el botón manualmente y agregar el controlador en el código de detrás. Algo así como:

marcado fragmento:

<asp:GridView ID="gvTest" runat="server" OnRowDataBound="gvTest_RowDataBound" /> 

código detrás:

protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if(e.Row.RowType == DataControlRowType.DataRow) 
    { 
     //find button in this row 
     LinkButton button = e.Row.FindControl("DeleteButton") as button; 
     if(button != null) 
     { 
      button.Click += new EventHandler("DeleteButton_Click"); 
     } 
    } 
} 

protected void DeleteButton_Click(object sender, EventArgs e) 
{ 
    LinkButton button = (LinkButton)sender; 
    // do as needed based on button. 
} 

No estoy seguro de cuál es el propósito del botón es, pero asumiendo que se trata de una fila de botones de eliminación, Puede que no desee tener este enfoque como en el controlador de eventos, no tiene acceso directo a la fila en cuestión, como lo haría con el evento RowCommand.

¿Hay algún motivo por el que esté utilizando el campo Plantilla? ¿Vs un ButtonField?Si usa un ButtonField, puede conectar el evento RowCommand.

marcado fragmento:

<asp:GridView ID="gvTest" runat="server" OnRowCommand="gvTest_RowCommand"> 
    <columns> 
     <asp:buttonfield buttontype="Link" commandname="Delete" text="Delete"/> 
     .... 
    </columns> 
</asp:GridView> 

código detrás:

protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e) 
{ 
    if(e.CommandName == "Delete") 
    { 
     //take action as needed on this row, for example 
     int rowIndex = Convert.ToInt32(e.CommandArgument); 
     GridViewRow currentRow = (sender as GridView).Rows[rowIndex]; 

     //do something against the row... 
    } 
} 

Es posible que desee consultar documentación de MSDN en algunos de estos temas:

EDIT:

Para responder a su pregunta sobre la ButtonField - Sí No veo por qué no podría todavía hacer frente a una ButtonField. He aquí un fragmento de encontrar el ButtonField durante datos de fila atados y esconderlo (no probado, pero creo que funcionaría ...)

protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     //let's assume your buttonfield is in column 1 
     // (you'd know this based on your markup...) 
     DataControlFieldCell cell = e.Row.Cells[1] as DataControlFieldCell; 
     if(cell != null) 
     { 
      ButtonField field = cell.ContainingField as ButtonField; 

      //based on your criteria, show or hide the button 
      field.Visible = false; 
      //or 
      field.Visible = true; 
     } 
    } 
} 
+0

El uso de un ButtonField, hay una manera de ocultar mediante programación o mostrarla? Puedo o no mostrar el botón, dependiendo de algún valor en la iteración actual. Todo lo que leí dijo que tenía que cambiar a un botón estándar en un TemplateField. Con mi método actual, estoy usando el evento RowDataBound para examinar la iteración actual, encontrar el botón y posiblemente ocultarlo. – Deane

+0

Creo que definitivamente sería posible. Edité mi respuesta con el código de muestra adjunto. –

-1
<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button> 
Cuestiones relacionadas