1

基本的に、ページの読み込み時にプレースホルダーをページに動的に追加しています。

次に、プレースホルダーに追加され、特定のページ イベントの実行時に表示される複合コントロールがあります。複合コントロールにはボタンがあります。複合コントロールで使用できるボタンのパブリック イベント ハンドラーがありますが、実際にはページ コードでこのイベント ハンドラーに直接アクセスすることはできません。

コントロールを表示するには、たとえば次の呼び出しを行います。

MyControl.Create(args, new EventHandler(OnClick)); 

次に、私が持っているページでprotected void OnClick(object o, EventArgs args) {}

もちろん、呼び出すときはcreate()、イベント ハンドラを複合コントロールのボタン クリック イベントに関連付けます。ここまでは順調ですね。ボタンが配線されていると、ボタンのクリックが期待どおりにコントロールにポストバックされます。ただし、イベントがページのイベント ハンドラーに戻ることはありません。

ポストバックで問題が発生していることに気づきました。しかし、init、load、または createchildcontrols でボタンを配線しようとしても、ページでイベントを処理できるように配線を適切に保つことができません。私が望むのは、実行時にイベントハンドラーを複合コントロールに渡し、複合コントロールがポストバック時にイベントを正しくページに送り返す機能です。

興味深いことに、カスタム eventargs を指定して OnBubble を呼び出すと、ページ上のバブル イベントをキャッチできます。しかし問題は、プレースホルダーがページ上にあることです。そのため、MyControl.Create()たとえば、UserControl を呼び出そうとすると、バブルは UserControl ではなくページに移動します (予想どおり)。したがって、オーバーライドするのではなく、イベントハンドラーを宣言することを好む理由ですOnBubble(MyControl を宣言する UserControls およびその他のコントロールは、ボタン クリック イベントに対して本質的に役に立たなくなります)。

誰かが問題について何らかの洞察を持っていることを願っています。興味深い問題のように思えますが、ページ上でコントロールを明示的に宣言し、マークアップまたはページロードでイベントを直接接続する以外に解決策はないかもしれません。ボタンで非同期コールバックを行うことを検討しますが、可能であれば標準の ASP.NET イベント処理を使用することをお勧めします。

ありがとう!

明確にするために、MyControl.Create()呼び出しは実際には複合コントロールのCreate()メソッドを呼び出すイベントを生成します。MyControl.Create()これで問題ありませんが、メソッドがコントロールに直接アクセスできないことに注意してください。コントロールはマークアップではなくページに追加されるため、これは理にかなっていますonload

より多くのコード:

MyControl : CompositeControl 
{
     public event EventHandler Click;

     //I have a create method
     void Create(args, EventHandler click)
     {
          this.Click = click;
          //other processing
     }

     //then the button is wired up. I've tried in OnInit(), OnLoad()
     void CreateChildControls()
     {
           MyButton.OnClick += Click;
     }

     //if I wire up the button to a default handler I can check if
       Click is not null and send the click event onto the next handler 
     //this is where the bubble event works, but the wiring fails
} 

編集:イベントハンドラーをセッションに保存し、ポストバックのボタンを接続する試みは成功しました。私はこれを良い習慣とは考えていませんし、実際に私の目的に役立っているとは思いません。たとえば、この場合、ページのイベントは期待どおりに実行されますが、ページの動作は標準的ではありません。たとえば、Response.Redirect() は例外をスローします。イベントハンドラーはポストバック中に状態情報を失った可能性があるため、これは理にかなっています。いくつかの考え: 1. このコントロールに何らかの形で関連するカスタム バブル イベントを作成することは可能ですか? これはもっともらしいように思えますが、ページのポストバックの問題により、バブルがどこに行くべきかという同じ問題が残ります。したがって、create() を呼び出すと、バブルの宛先として UserControl を自動的に登録することは可能ですか? 難しそうです。2. デリゲートがポストバックで正しく呼び出されるように、UserControl 宣言されたイベント ハンドラでイベントを再配線できるページ ライフサイクルのポイントはありますか? これは私が欠けているもののようです。イベント ハンドラはポストバックで作成されますが、OnClick 中に UserControl で再作成されないため失われます。UserControl で明示的に再作成する必要はありませんが、子コントロールで UserControl 用に再作成する必要があります。単純な要求のように聞こえますが、UserControl がループから外れると、不可能なことを要求している可能性があります。デリゲートがポストバックで正しく呼び出されるように、UserControl 宣言されたイベントハンドラーでイベントを再配線できるページ ライフサイクルのポイントはありますか? これは私が欠けているもののようです。イベント ハンドラはポストバックで作成されますが、OnClick 中に UserControl で再作成されないため失われます。UserControl で明示的に再作成する必要はありませんが、子コントロールで UserControl 用に再作成する必要があります。単純な要求のように聞こえますが、UserControl がループから外れると、不可能なことを要求している可能性があります。デリゲートがポストバックで正しく呼び出されるように、UserControl 宣言されたイベントハンドラーでイベントを再配線できるページ ライフサイクルのポイントはありますか? これは私が欠けているもののようです。イベント ハンドラはポストバックで作成されますが、OnClick 中に UserControl で再作成されないため失われます。UserControl で明示的に再作成する必要はありませんが、子コントロールで UserControl 用に再作成する必要があります。単純な要求のように聞こえますが、UserControl がループから外れると、不可能なことを要求している可能性があります。ただし、子コントロールで UserControl 用に再作成する必要があります。単純な要求のように聞こえますが、UserControl がループから外れると、不可能なことを要求している可能性があります。ただし、子コントロールで UserControl 用に再作成する必要があります。単純な要求のように聞こえますが、UserControl がループから外れると、不可能なことを要求している可能性があります。

4

4 に答える 4

1

ページのライフサイクルのどの時点でこれらのコントロールを作成および追加するかについては特に言及していません。ポストバックを機能させるには、すべての作成 (および配線) と「再作成」を page_load イベントの前に行う必要があります。

page_init でこれを行うと、ID が同じ場合、viewstate メカニズムがポストバック値を引き継ぐ必要があります。

ただし、ここで別の方法に出くわしました: http://www.codeproject.com/KB/viewstate/retainingstate.aspx

于 2009-07-19T14:32:32.940 に答える
0

さて、私が間違っている場合は訂正してください。Create()メソッドは実際にインスタンス化して、内部コントロールを既知の状態に設定します。ボタンへの参照がすでにあるようですが、なぜこの時点で追加のClickイベントが必要なのですか?

Create()を呼び出すと、コントロールとそのボタンが初期化され、ボタンがそこにあることがわかったら、そこに取得したパラメーターを渡してイベントハンドラーを接続します。

MyControl : CompositeControl
{
    void Create(args, EventHandler click)
    {
        // init & set up your control

        // other processing

        MyButton.OnClick += click;
    }
}
于 2009-07-19T14:24:48.850 に答える
0

動的に作成されたコントロールには常に同じ ID を設定する必要があります。そうしないと、コントロール イベントが発生しないことがあります。

この助けを願っています。

于 2010-05-27T18:10:53.797 に答える
0

コントロールをプレースホルダーに動的に挿入する動機は何ですか? リクエスト間にページは実際には存在しないため、動的に挿入されたコントロールは存続しません。あなたは基本的にそれを偽造する必要があります。

考慮すべきオプションの 1 つは、異なるレンダリング モードを持ち、一貫したイベント インターフェイスを持つカスタム コントロールを作成することです。もう 1 つは、ASP.NET MultiView コントロールを使用することです。これは、HTML で表示されるビューのみをレンダリングしますが、非表示のビューでイベント ハンドラーを維持します。

于 2009-07-18T17:19:29.957 に答える