6

かなりのプロセッサとディスクを集中的に使用する検索に基づいて、最初にボタンを生成する必要があります。各ボタンは選択を表し、ポストバックをトリガーします。私の問題は、ポストバックがコマンド b_Command をトリガーしないことです。元のボタンが再作成されていないためだと思います。ポストバックで元の検索を実行してボタンを再作成する余裕がないため、ポストバック情報から必要なボタンを生成したいと考えています。

どのように、どこでこれを行う必要がありますか? たとえば、Page_Load の前にそれを行う必要がありますか? ポストバックから CommandEventHandler を再構築するにはどうすればよいですか?

   namespace CloudNavigation
{
    public partial class Test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                // how can I re-generate the button and hook up the event here
                // without executing heavy search 1
            }
            else
            {
                // Execute heavy search 1 to generate buttons
                Button b = new Button();
                b.Text = "Selection 1";
                b.Command += new CommandEventHandler(b_Command);
                Panel1.Controls.Add(b);
            }
        }

        void b_Command(object sender, CommandEventArgs e)
        {
            // Execute heavy search 2 to generate new buttons
            Button b2 = new Button();
            b2.Text = "Selection 2";
            b2.Command += new CommandEventHandler(b_Command);
            Panel1.Controls.Add(b2);
        }
    }
}
4

6 に答える 6

5

b_Command イベント ハンドラー メソッドは実行されません。これは、ポスト バック ボタンが再作成されないためです (動的に生成されるため)。ページが再作成されるたびにそれらを再作成する必要がありますが、これを行うには、状態のどこかに情報を明示的にキャッシュする必要があります。

これがページ スコープの操作である場合、最も簡単な方法は、ViewState に格納することです (文字列として - オブジェクトを含む ViewState の読み込みを開始すると、パフォーマンスが低下することがわかります)。イベント)、ページのリロード時にボタンを再作成します。操作がセッション スコープの場合、オブジェクト (配列など) をセッションに簡単に格納し、次の読み込み (または初期化) でそれを取得して、コントロールを再作成できます。

このシナリオは、ボタンを作成して追加するのではなく、b_Command EventHandler にボタンに関する情報を保存するだけでよいことを意味します。これを行うと、次のポストバックで関連情報が失われるためです (現在発生しているように)。

したがって、コードは次のようになります。

namespace CloudNavigation
{
    public partial class Test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                this.recreateButtons();
            }
            else
            {
                // Execute heavy search 1 to generate buttons
                Button b = new Button();
                b.Text = "Selection 1";
                b.Command += new CommandEventHandler(b_Command);
                Panel1.Controls.Add(b);
                //store this stuff in ViewState for the very first time
            }
        }

        void b_Command(object sender, CommandEventArgs e)
        {
            //Execute heavy search 2 to generate new buttons
            //TODO: store data into ViewState or Session
            //and maybe create some new buttons
        }

        void recreateButtons()
        {
            //retrieve data from ViewState or Session and create all the buttons
            //wiring them up to eventHandler
        }
    }
}

ページの読み込み時に recreateButtons を呼び出したくない場合は、PreLoad または Init イベントで呼び出すことができます。どこからでも ViewState/Session 変数にアクセスできるため、違いはありません (Init ビューステートでは適用されません)。ただし、動的ボタンを再作成するためにアクセスできます)。

誰かがこのソリューションを嫌うでしょうが、私が知る限り、状態データをサーバー側で保持する唯一の方法はViewState - Session - Page.Transfer またはクライアント側の Cookie です。

于 2008-11-09T18:09:20.430 に答える
1

ボタンは load イベントの前に作成する必要があります。そうしないと、状態が正しく配線されません。代わりに Init() でボタンを再作成してください。

検索を再実行せずにこれを行う方法については、結果をどこかにキャッシュすることをお勧めします。キャッシュ内の結果セットの存在は、Init() イベントのボタン コードが実行する必要があることを認識する方法です。

または、ページにボタンを静的に配置することもできます。検索が返すものを処理するのに十分なだけそこに置いてください。アイテムが多すぎるのではないかと考えている場合は次のことを自問してください。ユーザーは本当にそんなに多くのアイテムを並べ替えたいと思うでしょうか? このデータのページングを検討する必要があるかもしれません。その場合、静的ボタンはもはやそれほど重要ではありません。

于 2008-11-07T18:07:23.243 に答える
1

ポストバック イベント処理が、コレクションに存在しないコントロールを見つけようとするとどうなりますか。チェックアウト Denis DynamicControlsPlaceholder @ http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

Bruno Figueiredo http://www.brunofigueiredo.comに役立つことを願っています

于 2008-11-07T18:22:10.577 に答える
0

カスタムビューステート処理のサンプルを次に示します(ボタンにはがありますEnableViewState = false)。

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            // Execute heavy search 1 to generate buttons
            ButtonTexts = new ButtonState[] { 
                new ButtonState() { ID = "Btn1", Text = "Selection 1" } 
            };
        }
        AddButtons();
    }

    void b_Command(object sender, CommandEventArgs e)
    {
        TextBox1.Text = ((Button)sender).Text;

        // Execute heavy search 2 to generate new buttons
        ButtonTexts = new ButtonState[] { 
            new ButtonState() { ID = "Btn1", Text = "Selection 1" }, 
            new ButtonState() { ID = "Btn2", Text = "Selection 2" } 
        };
        AddButtons();
    }

    private void AddButtons()
    {
        Panel1.Controls.Clear();
        foreach (ButtonState buttonState in this.ButtonTexts)
        {
            Button b = new Button();
            b.EnableViewState = false;
            b.ID = buttonState.ID;
            b.Text = buttonState.Text;
            b.Command += new CommandEventHandler(b_Command);
            Panel1.Controls.Add(b);
        }
    }

    private ButtonState[] ButtonTexts
    {
        get
        {
            ButtonState[] list = ViewState["ButtonTexts"] as ButtonState[];
            if (list == null)
                ButtonTexts = new ButtonState[0];
            return list;
        }
        set { ViewState["ButtonTexts"] = value; }
    }

    [Serializable]
    class ButtonState
    {
        public string ID { get; set; }
        public string Text { get; set; }
    }
于 2008-11-07T18:28:36.490 に答える
0

ASPX にイベント ハンドラーが接続されていますか?

<asp:Button id="btnCommand" runat="server" onClick="b_Command" text="Submit" />
于 2008-11-07T18:03:02.877 に答える
0

検索結果のキャッシュについては Joel に同意します。ボタンに関しては、ページ ライフサイクルの init または load フェーズで動的に作成できますが、ボタンを削除してからプログラムで追加し直すと、状態が台無しになることに注意してください。

私のプロジェクトの 1 つで、フィールドをその場で生成する動的フォームがあり、それを機能させる方法は、ページのキャッシュまたはビューステートに格納されている配列を使用することです。配列には表示するボタンが含まれており、各ページの読み込み時にボタンを再作成して、状態を適切に読み込むことができるようにします。次に、さらに多くのボタンまたはまったく新しいセットが必要な場合は、配列内の非表示値にフラグを立て、対応するボタンの新しいセットの配列に新しい値のセットを追加します。この方法では、状態は失われず、ボタンは引き続き機能します。

また、ボタンをプログラムで作成する場合は、ボタンの on_click イベントのハンドラーを追加する必要があります。これは、コードの上部に表示されていると思います。

于 2008-11-07T18:16:04.833 に答える