2

これはおそらく重複のように見えますが、私はそうは思いません。私はすでにstackoverflowを検索しましたが、十分ではない可能性があります。

これが私の挑戦です:

<asp:LinkButton runat="server" ID="DeleteRow" CommandName="deleterow" 
   CommandArgument='<%# Eval("ID") %>' Text="Delete" 
   OnClientClick="return confirm('Are you sure you want to delete this record?');" /> 

リンクを初めてクリックした場合、OnRowCommandは起動されません。2回目にクリックすると、機能します。

ソースを調べたところ、これらの違いがあります。

//When you first load the page: the GUID is the PK for that row 
1. javascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')

//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')

クリックの前と後hrefののから2つのコードをコピーしました。asp:LinkButton

なにが問題ですか?私のページには他に1つのイベントしかありませんRowDataBound

  protected void gvSchoolClasses_RowDataBound(object sender, GridViewRowEventArgs e)
  {
        e.Row.ID = Guid.NewGuid().ToString();
  }

  protected void Page_Load(object sender, EventArgs e)
  {
        CheckAuthentication();

        if (!Page.IsPostBack)
        {
            ClassesAcademicYearLabel.Text = "- Year " + Setting.Year;
            //FillClassesList();  //filling some combo boxes. Have checked the codes here too
            //FillLettersList();  //they didn't affect the Grid
            FillGrid();
        }

        ClassErrorLabel.Visible = false;

  }
4

3 に答える 3

3

イベントの行のIDプロパティを設定することにより、RowDataBound観察している問題を作成しました。

ページのコントロールがコレクションに追加されるまでイベントは発生しないためRowDataBound、ASP.NETには既に計算されたクライアント参照を更新する方法がありません。したがって、コマンドは期待どおりに実行されません。

CommandArgumentすでにイベントで生成されたIDにプロパティを設定していることに気付きました。RowDataBoundこれも問題の一部である可能性があります(イベントの発生順序によって異なります。パイプラインチャートは手元にありません)。

編集:これの簡単な修正は、ClientIDプロパティ(申し訳ありませんが、正確な名前ではありませんが、インテリセンスが残りの方法を取得するはずです)を自動決定ではなく手動に設定することです。そうすれば、設定したIDがフレームワークによって変更されることはありません。

この問題が発生する理由についてもう少し詳しく説明するために、提示されたクライアント側IDについて考えてみます。

ctl00$content$gvSchoolClasses$ctl02$DeleteRow

このIDは、宣言されたID(DeleteRow)を取得し、コントロール階層を上に移動して親IDを文字列の前に追加することにより、(このページで)一意であることが保証されます。getElementByIdJSコードは、この文字列をに渡すと、一貫性のある予測可能な方法で動作することを確信できます。

上記のIDを生成できるようにするには、階層内のすべてのコントロールがすでに存在し、レンダリングエンジンによって考慮されている必要があります。

ここで、コントロールのIDプロパティが変更されたときに何が起こるかを考えてみましょう(これは、ClientIDではなく、単に名前が付いたプロパティであることに注意してくださいID)。

ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow

cl02行の名前付けコンテナ( )の代わりに、生成して割り当てたGUIDが含まれていることに注意してください。以前に割り当てられたIDを使用してこのコンテナにアクセスしようとするクライアントJSは、期待どおりに機能しなくなるため、がっかりします。

ASP.NETコントロールがへの呼び出しを介してポストバックを起動したときjavascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')

ポストバックは問題なく実行されますが(ポストバックのフォームパラメータを調べることで確認できます)、サーバーがリクエストを処理すると、存在しないコントロールを(ビューステートから)再水和しようとします。 。その結果、コマンドが発行されたことを認識しないコントロールの新しいインスタンス(正しいIDを使用)が作成されるため、XXXCommandイベントが発生することはありません。データバインディングが発生していないため(ポストバックであり、コードがその状態を正しくチェックします)、IDがリセットされることはなく、コマンドを正常に起動できます。

于 2012-07-10T19:35:16.197 に答える
1

RowDataBoundイベントのRow.IDを変更しないでください。グリッドで別の値を変更するか、グリッドビューマークアップでこれを行います。

CommandArgument ='<%:Guid.NewGuid.ToString(); %> '

コードビハインドでそれを実行したい場合は、次のようにすることができます。

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            LinkButton deleteRow = (LinkButton)e.Row.FindControl("DeleteRow");
            if (deleteRow != null)
                deleteRow.CommandArgument = Guid.NewGuid().ToString();
        }
于 2012-07-10T19:56:18.463 に答える
0

行インデックスをGUIDではなくリンクボタンのCommandArgumentに設定する必要があります

あなたが2回目に動作すると言ったように、htmlは以下のようになります

//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')
于 2012-07-10T19:39:28.000 に答える