none
UpdatePanelがなぜか順番に更新されない RRS feed

  • 質問

  • いつもお世話になっております。

    さっそくですが、グラフを4つ配置したページがあり,DropDownListから対象期間を選ぶとグラフが1個ずつ時間差で生成・更新されるようにしたいのですがどうしても4つとも一度に更新されてしまいます。

    ページの構成を簡単にご説明します。各グラフはPanelの中に挿入されるのですがそれぞれUpdatePanelに入っています.

    パネル部分====================================

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
      <ContentTemplate>
                        <asp:Panel ID="Panel1" runat="server" Height="350px" Width="600px">
                        </asp:Panel>
      </ContentTemplate>
    </asp:UpdatePanel>
    ========================================

    グラフ生成部分(VB)===============================

    Public Function GetDayByDayChartHtml() As String

    省略

            Panel1.Controls.Clear()

            Panel1.Controls.Add(New LiteralControl(outPut))
            oRs.ReadData.Close()
        End Function
    終わり======================================

    これが4セットあります。

    以下のようにComboboxが変更されると、この4つのイベントを順に実行するようにしていて間にsleepを入れているのですが、
    順番にならずに、sleepを待った後に一度に更新されます。 どうすれば順番に更新されるようになるか教えていただけますか?

    ========================================
        Protected Sub ASPxComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ASPxComboBox1.SelectedIndexChanged
            GetDayByDayChartHtml()
            System.Threading.Thread.Sleep(1000)
            GetHourByHourChartHtml()
            System.Threading.Thread.Sleep(1000)
            GetDoc_RankingChartHtml()
            System.Threading.Thread.Sleep(1000)
            GetFocusAreaChartHtml()
        End Sub
    ========================================

    よろしくおねがいします。

     

    2011年6月7日 1:30

回答

  • Web アプリと Windows アプリは違うということを理解して、それを強
    く意識して開発しましょう。そのことがわかってないと、今回のように
    的外れなことをしていても気がつかず、深みにはまるばかりだと思いま
    す。

    順番に表示するという見せ掛けだけの問題であれば、今までどおり 4
    パネル全部一度に更新を済ませてクライアントに最終結果だけを返し、
    クライアントスクリプトでパネルを順次表示していくようにしてはい
    かがですか?
    そうではなくて、4 パネルの非同期ポストバックの順序を制御したい
    ということであれば、以下のような方法が考えられます。
    ScriptManager と UpdatePanel コントロールを使用しての非同期ポス
    トバックは、内部で PageRequestManager クライアントオブジェクト
    が関係しています。
    PageRequestManager はクライアント側で発生する以下のイベントを提
    供しており、これらを利用して部分ページ更新のリクエストとレスポ
    ンスの処理をカスタマイズできます。
    initializeRequest
    beginRequest
    pageLoading
    pageLoaded
    endRequest
    PageRequestManager と各イベントの詳細は以下の MSDN ライブラリを
    参照してください。
     
     
    今回のケースの場合、各 UpdatePanel に個別に非同期ポストバックのト
    リガを設けておき、最初に更新する UpdatePanel のみ ComboBox の
    SelectedIndexChanged でトリガをかけし、残りは順番に 1 つずつ、先
    の更新の endRequest イベントで次のパネルの更新のトリガをかけると
    いう案が考えられます。
    でも、そんな必要はないですよね?
    • 回答としてマーク tosaito3 2011年6月10日 4:04
    2011年6月7日 13:59

すべての返信

  • ASP.NETは基本的な動作として、1つのページの中の処理を全部終了したうえで生成したHTMLをブラウザに返す、という形になっています。
    なので、プログラムに書いてあるとおりの動作が行われており、なにも問題はないですね。

    サーバー側の処理ではどうしようもない(Response.Flushでなんとかする方法があるのかもしれませんが)ところかと思うので、クライアント側に作成するJavaScriptと組み合わせてうまく動作するような形を考えていくしかないと思います。


    あおい情報システム株式会社 小野修司(どっとねっとふぁん)
    2011年6月7日 2:39
  • 小野@どっとねっとふぁん様

    ありがとうございます。やはりそうですか。 

    4つのグラフそれぞに個別のDropDownListを作成してTrigerを分けて、グラフを描画するイベントの最終行に次のグラフ描画イベントのトリガーになっているDropDownListを適宜選択するようにすればどうかと思いやってみたのですが、うまくいきません。DropDownList1で選ばれているものを例えばDropDownList2でも選択させる場合は以下のような書き方で正しいのでしょうか?

    どうやら書き方がわるいのではないかと思っています。

    DropDownList2.Items.FindByText(DropDownList1.Text).Selected = True

    よろしくおねがいします。

    2011年6月7日 8:19
  • > グラフを描画するイベントの最終行に次のグラフ描画イベントのトリガーになっているDropDownListを適宜選択するようにすればどうかと思いやってみたのですが

    このようにサーバー側の一連の処理でやろうとするのは同じことだというのが理解できてないようですね。
    なんらかのクライアント側の処理が必要だと思います。

     


    あおい情報システム株式会社 小野修司(どっとねっとふぁん)
    2011年6月7日 8:59
  • Web アプリと Windows アプリは違うということを理解して、それを強
    く意識して開発しましょう。そのことがわかってないと、今回のように
    的外れなことをしていても気がつかず、深みにはまるばかりだと思いま
    す。

    順番に表示するという見せ掛けだけの問題であれば、今までどおり 4
    パネル全部一度に更新を済ませてクライアントに最終結果だけを返し、
    クライアントスクリプトでパネルを順次表示していくようにしてはい
    かがですか?
    そうではなくて、4 パネルの非同期ポストバックの順序を制御したい
    ということであれば、以下のような方法が考えられます。
    ScriptManager と UpdatePanel コントロールを使用しての非同期ポス
    トバックは、内部で PageRequestManager クライアントオブジェクト
    が関係しています。
    PageRequestManager はクライアント側で発生する以下のイベントを提
    供しており、これらを利用して部分ページ更新のリクエストとレスポ
    ンスの処理をカスタマイズできます。
    initializeRequest
    beginRequest
    pageLoading
    pageLoaded
    endRequest
    PageRequestManager と各イベントの詳細は以下の MSDN ライブラリを
    参照してください。
     
     
    今回のケースの場合、各 UpdatePanel に個別に非同期ポストバックのト
    リガを設けておき、最初に更新する UpdatePanel のみ ComboBox の
    SelectedIndexChanged でトリガをかけし、残りは順番に 1 つずつ、先
    の更新の endRequest イベントで次のパネルの更新のトリガをかけると
    いう案が考えられます。
    でも、そんな必要はないですよね?
    • 回答としてマーク tosaito3 2011年6月10日 4:04
    2011年6月7日 13:59
  • アドバイスありがとうございます。 まだ完全ではないのですが以下のようにクライアント側のJavaScriptで時間差更新をやろうとしています。 function update_dropdown_list(DropDownList2, DropDownList1) { var src_element = document.getElementById(DropDownList2); var dst_element = document.getElementById(DropDownList1); setTimeout( function() { var index = src_element.selectedIndex; dst_element.selectedIndex = index; }, 3000); } よろしくおねがいします。
    2011年6月8日 8:25
  • > 以下のようにクライアント側のJavaScriptで時間差更新をやろうとし
    > ています。

    そのやり方ではダメだと思います。レスを読んでもらってますか?

     

    2011年6月8日 12:28
  • 申し訳ありません。 先に取り掛かっていたのでJavaScriptでちょっとやってみました。一応DropDownList1が変更されたXX秒後にDropDownList2がDropDownList1と同じ値に変更されるようにすることはできましたが、いったん止めてPageRequestManagerのほうでやってみてご報告いたします。

    function sync_dropdown_list() {
        var DropDownList1_element = document.getElementById("DropDownList1");
        var DropDownList2_element = document.getElementById("DropDownList2");
        var index = DropDownList1_element.selectedIndex;
        DropDownList2_element.selectedIndex = index;
    }

    <asp:dropdownlist ID="DropDownList1" runat="server" AutoPostBack="True"
                DataSourceID="SqlDataSource_Combobox1" DataTextField="AccessDate"
            DataValueField="AccessDate"  
                onchange="setTimeout('sync_dropdown_list()',5000)">
            </asp:dropdownlist>

    よろしくおねがいします。

    2011年6月9日 1:28
  • > 一応DropDownList1が変更されたXX秒後にDropDownList2がDropDownList1と
    > 同じ値に変更されるようにすることはできましたが、

    提供されている情報ではよく分かりませんでしたが、要するに、UpdatePanel1
    に非同期ポストバックをかける ==> XX 秒後に UpdatePanel2 に非同期ポスト
    バックをかける ==> その XX 秒後に UpdatePanel3 に非同期ポストバックを
    かける ==> ・・・というように JavaScript で操作すると言うことですか?

    その場合、先の非同期ポストバックによる UpdatePanel の更新が必ず XX 秒
    以内に完了しないとうまくいかないので、それを保証するために XX 秒を長く
    取れば、ユーザーが必要以上に待たされることになると思います。それが許さ
    れるのであれば、せっかくうまくいったそうなので、その方法でもいいと思い
    ますが・・・

    最初の質問をみると、4 つの UpdatePanel を一度に更新することは出来るよ
    うですが、何故それではダメなのですか?
    2011年6月9日 13:19
  • SurferOnWwwさま

    お世話になります。

    はい。これだとご指摘の通りUpdatePanelの更新が完了するかどうかに関係なく時間差で更新されてしまうので、更新がその間に完了しない場合を考えると完ぺきではありません。よくわからなかったのはDropDownListの値の時間差変更まではできたのですが、そのDropDownListがトリガーになっているUpdatePanelはなぜか更新されませんでしたのでいったんあきらめました。手で変更すると更新されす。

    なお、以下のページの例を参考にendRequest イベントでもやってみたのですが、1ページあたり1回はイベントを発生させられるのですが、2回、3回となると難しくて断念しました。

    http://codeasp.net/blogs/raghav_khunger/microsoft-net/960/call-javascript-function-after-updatepanel-has-fired-server-side-code

    そもそもやる必要がないのは確かですが、4つのUpdatePanelが一度に更新されると画面がヘッダー以外真っ白になるのであまり見た目が良くない気がしたので、簡単に時間差で更新できないかなと思った次第です。

    いろいろと勉強になりました。今後ともよろしくお願いします。

    2011年6月10日 4:03