2

これは2日間私を夢中にさせています-誰かがこれを前に見たことを願っています.

リピーターまたはグリッド ビュー内のコントロールの最初のクリックが ItemCommand イベントの発生に失敗し、その後のすべてのクリックが機能するというこの問題があります。コントロールは Base.aspx のプレースホルダーにロードされています。

    private void LoadUserControl()
    {
        string controlPath = LastLoadedControl;

        if (!string.IsNullOrEmpty(controlPath))
        {
            ph.Controls.Clear();

            UserControl uc = (UserControl)LoadControl(controlPath);
            ph.Controls.Add(uc);
        }

    }

これがビューステートの問題なのか、どのページ イベントで DataBind() を使用する必要があるのか​​ 疑問に思っています。さまざまなページ イベントでデータ バインドを試し、ページのビューステートとコントロールを結果の変動なしで有効にしました。

これがGridViewテンプレートですが、リピーターコントロールでも同じ動作をするので、この問題であるコントロールは信じられません。

<ItemTemplate>
       <asp:RadioButton ID="rbEnable" GroupName="MyGroup" runat="server" Text="Enabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive == true %>" />
       <asp:RadioButton ID="rbDisable" runat="server" GroupName="MyGroup" Text="Disabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive != true %>" />
       <asp:Button ID="btnEnable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" CommandName="Enable" ToolTip="Enable" Text="Save" />
       <asp:Button ID="btnDisable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" Visible="false" CommandName="Disable" ToolTip="Disable" Text="Disable" />
    </ItemTemplate>

関連する可能性のある詳細情報:

私が気付いたのは、ユーザーコントロールの Page_Load イベントで、コントロールを再バインドしている場所です。これはおそらくコントロールの状態が書き換えられるための原因ですが、ascx のこの領域に if(!IsPostback) を追加すると、このコード セクションは aspx ページのようにまったく起動しません。これは、コントロールを再バインドするための正しいセクションだと思います。

4

3 に答える 3

8

MikeW、
これを何時間もいじった後、私はあなたの問題の根本を見つけました.
リピーターやグリッドビューとは特に関係ありません。
これは単に、ポストバック上の動的制御の問題です。

問題を解決するには:
驚くべきことに、コードに 1 行しかありません。
コントロールをロードするときに、次のようにその ID に何かを割り当てます。

UserControl uc = (UserControl)LoadControl(controlPath);
uc.ID = "mycontrol";
ph.Controls.Add(uc);

そうすれば、ポストバックすると、ページはどのコントロールがどれであるかを認識します。

これをより簡単に説明するために、問題を単純化しましょう。
ボタンを連続して 2 回クリックして、別のボタンを動的に作成するシナリオを次に示します。

  • 1 つのボタン Button1 を作成します。このボタンをクリックすると、別のボタン Button2 が動的に読み込まれます。Button2 のアクションが現在の時刻を表示するのと同じくらい単純であると仮定します。
  • ここで、Button1 をクリックします。
  • Button2 を保持するViewStateには、動的コントロールがあることをページに伝えるために使用する必要があります。あなたがしたように、コントロールのパス、またはそのクラスの名前を覚えることができます。
  • ページがポストバックするとすぐに、保持しようとしているコントロールがあることを確認Page_LoadするViewStateために を見て、そこにそれをロードします (これはLoadUserControl()上記の関数と同等です)。
  • ここまでで、Button2 が表示され、クリックすると正常に動作します。
  • Button2 をクリックしないで、もう一度 Button1 をクリックします (これは、2 つの異なる動的コントロールを切り替える場合と同じです)。
  • 今何が起こるかを推測してください: Page_Loadから Button2 をロードしますViewState。そして、ClickButton1 のイベントは、プレースホルダーをクリアした後、別の Button2 インスタンスをロードします。
  • ID を割り当てなかったので、それ自体に ID が割り当てられ、これら 2 つの Button2 はctl02ctl03UniqueIDのようなものになります。
  • ここで、Button2 をクリックします。
  • あなたは「それでいい、古いものを上書きしている」と言うでしょう。はい。ただし、ID がないわけではありません。
  • ポストバックで識別するための ID を指定しなかったため、UniqueID順次生成される を使用します。
  • 現在、ページは存在しないctl03を探しているため、起動Clickしません。
  • しかし、今では、 ctl02 を持つUniqueID 真新しい Button2があります。
  • この新しい Button2 をクリックすると問題なく動作します。ポストバックでは、これが唯一の Button2 であるため、偶然にもctl02UniqueIDが含まれます。

では、ID を割り当てるとどのように機能するのでしょうか? そうすれば、生成された新しいコントロールはそれぞれ同じ ID を持つため、ポストバック時に、それが別のボタンのイベント
で生成されたかどうかに関係なく、探しているものを見つけることができます。Page_LoadClick

それが機能する理由を説明してくれることを願っていますが、気にする限り、ID を割り当てるだけですべてがうまくいきます。
その背後にあるメカニズムと、その理由を共有できれば興味深いと思いました。=)

于 2010-10-28T22:41:53.897 に答える
1

コードの残りの部分についてはわかりませんが、通常、このような「最初のアクションの動作が後続のアクションとは異なる」という問題が発生するのは、IsPostBackセクションの間違った側に何かを配置したためです。

たとえば、ポストバックの場合は拘束力があるため、イベントは2番目のポストバックまで機能しません。最初のポストバックはイベントが発生したときであり、最初のページロードではその部分は実行されませんでした。

あなたは正しい道を進んでいると思います。適切なタイミングでイベントをバインドおよび配線していることを確認してください。

于 2010-10-27T19:14:18.687 に答える
1

私はそれを理解しましたが、理由はわかりません。
元のコードは次のとおりです。

Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)

データソースを設定してバインドする前に、テーブルを表示してプレースホルダーに追加するように変更しました。問題が解決しました。

Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)
Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
于 2012-03-13T12:15:08.710 に答える