2010-02-02 13 views
7

Ho un LinkButton all'interno di un GridView (tramite un TemplateField). Non importa quello che provo, il LinkButton non invocherà il suo gestore di eventi. Ho provato sia:Perché il mio LinkButton all'interno di GridView non solleva il suo evento OnClick?

  1. un gestore di eventi tradizionali ("OnClick")
  2. Un OnRowCommand gestore di eventi a livello di GridView.

In entrambi i casi, ho eseguito il debug e non rileva nemmeno il gestore di eventi.

Se sposto il LinkButton nella pagina (quindi non è in GridView), funziona correttamente, quindi so che la sintassi è corretta.

Ecco il metodo "tradizionale":

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

La cosa interessante è se mi tolgo il metodo "CancelThis" dal codice dietro, si genera un errore. Quindi so che è consapevole del suo gestore di eventi, perché lo cerca quando compila.

Ecco il metodo RowCommand:

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

In questo caso, il GridView ha:

OnRowCommand="GridView_RowCommand" 

E postsback, ma mai accenni a sensibilizzare l'evento.

Qualche idea di cosa mi manca qui?

risposta

0

ViewState è attivato su GridView? Questo mi ha catturato molte volte.

10

Come si lega il tuo GridView? Stai usando un controllo dell'origine dati? Se si esegue il binding manualmente durante il Page_Load, è possibile che poiché la griglia è vincolante per ogni round trip, il gestore eventi non sta recuperando correttamente. Se questo è il caso, si consiglia di provare qualcosa di simile:

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

potete inserire campione codice vincolante per andare con il vostro codice?

Se si in realtà si desidera forzare il problema, è possibile collegarsi all'evento RowDataBound sulla griglia, trovare il pulsante manualmente e aggiungere il gestore nel codice sottostante. Qualcosa di simile:

markup frammento:

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

dietro:

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. 
} 

Non sono sicuro di quale sia lo scopo del pulsante è, ma ammesso che sia una fila pulsante di eliminazione, è potrebbe non voler adottare questo approccio come nel gestore di eventi, non si ha accesso diretto alla riga in questione, come si farebbe con l'evento RowCommand.

C'è un motivo per cui si sta utilizzando il campo Modello? Vs dire un ButtonField?Se si utilizza un ButtonField, è possibile collegarsi all'evento RowCommand.

markup frammento:

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

codice dietro:

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... 
    } 
} 

si potrebbe desiderare di consultare documentazione MSDN su alcuni di questi argomenti:

EDIT:

Per rispondere alla tua domanda sul ButtonField - sì non vedo il motivo per cui non si poteva ancora fare con un ButtonField. Ecco un frammento di trovare la ButtonField durante dati delle righe rilegati e nasconderlo (non testato, ma credo che avrebbe funzionato ...)

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

Utilizzando un ButtonField, c'è un modo per nascondere a livello di codice o di mostrarlo? Potrei o non posso mostrare il pulsante, a seconda di qualche valore nell'iterazione corrente. Tutto ciò che ho letto diceva che dovevo passare a un pulsante standard in un TemplateField. Con il mio metodo corrente, sto usando l'evento RowDataBound per esaminare l'iterazione corrente, trovare il pulsante e potenzialmente nasconderlo. – Deane

+0

Penso che sarebbe sicuramente possibile. Modificato la mia risposta con il codice di esempio aggiunto. –

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