Почему мой LinkButton внутри GridView не вызывает событие OnClick? - PullRequest
7 голосов
/ 02 февраля 2010

У меня есть LinkButton внутри GridView (через TemplateField).Что бы я ни пытался, LinkButton не будет вызывать свой обработчик событий.Я пробовал оба:

  1. Традиционный обработчик событий ("OnClick")
  2. Обработчик событий OnRowCommand на уровне GridView.

В обоих случаяхЯ отладил, и он даже не перехватывает обработчик событий.

Если я переместу LinkButton на страницу (так что его нет в GridView), он будет работать нормально, поэтому я знаю, что синтаксис

Вот "традиционный" метод:

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

Интересно, если я уберу метод "CancelThis" из кода позади, он выдаст ошибку.Так что я знаю, что знает о своем обработчике событий, потому что он ищет его при компиляции.

Вот метод RowCommand:

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

В этом случае GridView имеет:

OnRowCommand="GridView_RowCommand"

Он выполняет обратную передачу, но никогда не намекает на поднятие события.

Есть идеи, что мне здесь не хватает?

Ответы [ 3 ]

10 голосов
/ 02 февраля 2010

Как вы связываете свой GridView? Используете ли вы контроль источника данных? Если вы выполняете привязку вручную во время Page_Load, возможно, так как сетка привязывается при каждом цикле, обработчик событий не перехватывает должным образом. Если это так, вы можете попробовать что-то вроде:

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

Можете ли вы опубликовать пример кода привязки для разметки?

Если вы действительно хотите вызвать проблему, вы можете подключиться к событию RowDataBound в Grid, найти кнопку вручную и добавить обработчик в коде. Что-то вроде:

Фрагмент разметки:

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

код позади:

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

Я не уверен, какова цель кнопки, но, предполагая, что это кнопка удаления строки, вы, возможно, не захотите использовать этот подход, так как в обработчике событий у вас нет прямого доступа к строке в вопрос, как если бы вы использовали событие RowCommand.

Есть ли причина, по которой вы используете поле Шаблон? Vs говорят ButtonField? Если вы используете ButtonField, вы можете подключиться к событию RowCommand.

фрагмент разметки:

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

код позади:

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

Возможно, вы захотите обратиться к документации MSDN по некоторым из этих тем:

EDIT:

Чтобы ответить на ваш вопрос о ButtonField - да, я не понимаю, почему вы все еще не можете разобраться с кнопочным полем. Вот фрагмент кода, чтобы найти поле кнопки во время привязки данных строки и скрыть его (не проверено, но я думаю, что это будет работать ...)

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 голосов
/ 05 октября 2015
<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>
0 голосов
/ 02 февраля 2010

Включено ли viewstate на вашем GridView? Это поймало меня много раз.

...