8

(TemplateField を介して) GridView 内に LinkBut​​ton があります。何を試しても、LinkBut​​ton はそのイベント ハンドラーを呼び出しません。私は両方を試しました:

  1. 従来のイベント ハンドラー ("OnClick")
  2. GridView レベルの OnRowCommand イベント ハンドラー。

どちらの場合も、デバッグしましたが、イベント ハンドラーをキャッチすることさえできません。

LinkBut​​ton をページの外に移動すると (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"

ポストバックしますが、イベントの発生を示唆することはありません。

ここで何が欠けているのか分かりますか?

4

3 に答える 3

10

どのようにバインドしていますGridViewか? データソース コントロールを使用していますか? 中に手動でバインドしている場合Page_Load、グリッドがすべてのラウンド トリップをバインドしているため、イベント ハンドラーが適切にキャッチしていない可能性があります。このような場合は、次のようなことを試してみてください。

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

マークアップに合わせてサンプル バインディング コードを投稿できますか?

本当に問題を強制したい場合は、Grid の RowDataBound イベントにフックし、ボタンを手動で見つけて、ハンドラーをコード ビハインドに追加することができます。何かのようなもの:

マークアップ スニペット:

<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ます。

テンプレート フィールドを使用している理由はありますか? 対言う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 のドキュメントを参照してください。

編集:

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;
        }
    }
}
于 2010-02-02T19:00:35.990 に答える
0

GridView でビューステートがオンになっていますか? これは何度も私を捕まえました。

于 2010-02-02T17:29:32.387 に答える
-1
<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>
于 2015-10-05T11:34:43.213 に答える