2009-07-18 16 views
1

本質的に、ページロード時に動的にページにプレースホルダを追加しました。ASP.netは動的にコントロールイベント処理を作成しました

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

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

次に、ページ上の私はもちろんprotected void OnClick(object o, EventArgs args) {}

を持っているでしょう:

コントロールを表示するには、私は、例えば、次の呼び出しを行いますコンポジットコントロールのボタンクリックイベント。ここまでは順調ですね。ボタンをワイヤでクリックすると、ボタンクリックがコントロールに正常にポストバックされます。ただし、イベントはページのイベントハンドラに戻されることはありません。

私はこの問題がポストバックで発生していることを認識しています。しかし、init、load、またはcreatechildcontrolsのボタンをワイヤリングしようとすると、ワイヤリングを維持してイベントをページ上で処理できなくなります。私が望むのは、イベントハンドラを実行時にコンポジットコントロールに渡し、コンポジットコントロールがポストバック時にイベントを正しくページに返すことです。

興味深いことに、カスタムイベントタグを使用してOnBubbleを呼び出すと、ページ上でバブリングされたイベントを捕捉できます。しかし問題は私のプレースホルダがページ上にあることです。たとえば、私がMyControl.Create()をUserControlで呼び出そうとすると、バブルはページに移動し、UserControlでは(期待通りに)移動しません。したがって、私はOnBubble(UserControlsとMyControlを宣言する他のコントロールはボタンクリックイベントのために無用にレンダリングする)をオーバーライドするのではなく、イベントハンドラを宣言することを好む理由です。

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

ありがとうございます! 呼び出しは、複合コントロールの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 
} 

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

+0

実際にハンドラを配線するコードをいくつか追加できますか? – user134706

+0

私はあなたがそこにイベントハンドラを格納することによってメモリをリークすると確信しています;) – user134706

答えて

0

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

異なるレンダリングモードを持つが、一貫したイベントインターフェイスを持つカスタムコントロールを作成することを検討してください。別の方法は、ASP.NET MultiViewコントロールを使用する方法です。このコントロールは、HTMLで表示可能なビューのみをレンダリングしますが、不可視ビューにイベントハンドラを保持します。

+0

応答をありがとう。コントロールは、多くのアプリケーションとほぼすべてのページで頻繁に使用されます。ページにコントロールを動的に挿入しようとする主な動機は、httpmoduleを使用して.configファイルの1行を使用してコントロールを挿入できるようにすることです...開発の容易さ、コードの再利用の容易さ、およびページの保守性の向上のためです。 私は提案を感謝し、それらをさらに調べます。私がそこで使うことができる解決策を見つけたら私はポストバックするでしょう。 –

0

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

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

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

     // other processing 

     MyButton.OnClick += click; 
    } 
} 
+0

イベントハンドラ自体は、親ページまたはUserControlで宣言されています。実際には余分なイベントハンドラは必要ありませんが、ポストバックでこのイベントが失われているので、イベントにキャッチしてOnBubbleを呼び出すことができるように、コントロールにイベントハンドラを書き込んでいます。イベントハンドラをセッションに保存してoninitまたはonloadを再実行すると、PageまたはUserControlはイベントをキャプチャしますが、安定した状態ではないことに気付きました。 –

1

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

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

私はかかわらず、ここに別の方法に遭遇しました

http://www.codeproject.com/KB/viewstate/retainingstate.aspx

0

あなたは常に動的にコントロールを作成するために同じIDを置く必要があり、あなたはそれに失敗した場合、時にはコントロールのイベントが発生していない、

希望この助けて。

関連する問題