2011-07-08 14 views
3

単純なASPページでは、TextBox AutoPostBackイベントはボタンのクリックイベント(ボタンが非常に速くタップされる場所を除く)と他のコントロール(ListBoxなど)のAutoPostBackイベントを防ぎます。TextBox AutoPostBackはさらにイベントを先取りします

あり、ここで同様の問題だが、私は、クライアント側やAJAXのソリューションを使用することを余儀なくされていると満足していませんでした:Have to click button twice in asp.net (after autopostback textbox)

例ASPXページ:背後

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="temp.aspx.cs" Inherits="temp" %> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" > 
    <head runat="server"> 
     <title>Untitled Page</title> 
    </head> 
    <body> 
     <form id="form1" runat="server"> 
     <div> 
      <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True" OnTextChanged="PostBack"></asp:TextBox> 
      <asp:Button ID="Button1" runat="server" OnClick="PostBack" Text="Button" /><br /> 
      <asp:ListBox ID="ListBox1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="PostBack"> 
       <asp:ListItem>value1</asp:ListItem> 
       <asp:ListItem>value2</asp:ListItem> 
      </asp:ListBox><br /> 
      <br /> 
      Events Fired:<br /> 
      <asp:TextBox ID="TextBox2" runat="server" Height="159px" TextMode="MultiLine" Width="338px"></asp:TextBox></div> 
     </form> 
    </body> 
    </html> 

C#コード:

public partial class temp : System.Web.UI.Page 
{ 
    protected void PostBack(object sender, System.EventArgs e) 
    { 
     this.TextBox2.Text += string.Format("PostBack for - {0}\n", ((System.Web.UI.Control)sender).ID); 
    } 
} 

クリックイベントの代わりにmousedownを使用してボタンのこの問題を部分的に解決することができました(私は余分なAutoPostBもブロックしました) ackイベントをクライアント側で実行し、ボタンクリックイベント中に余分なフィールドの変更を処理した場合)

しかし、これは私のボタンが標準(リリース時にクリック)のように動作していないことを意味します。

javascriptクライアント側ですべてを実行する必要はありませんが、この問題の解決策はありますか? (これらのポストバック中にサーバーデータを読み込むコードをたくさん書いているので、JavaScriptは理想的なソリューションではありません)。

これらのページのAJAXライブラリに切り替えることも避けようとしています。私はセキュリティ監査などを経なければならない。

注:私は現在、ASP.Net 2.0/VS 2005で作業していますが、このタイプの問題が、それ以降のリリースで修正されていれば、それは魅力的な引数。 (私が理解する限り、ASP.Net 4/VS 2010でも同じ問題が起きているようです)

+0

入力が変更されたときに自動的にポストバックしようとしていますか?これは古風なようですか?ボタンをフォームを送信する方法にしたい場合は、入力コントロールのオートポストバックプロパティを取り出します。 –

+1

おそらくあなたの望む機能がここで助けになると書いています。あなたはオートポストバックのすべてで何を達成しようとしていて、通常のクライアントサイドの機能を操作していますか? –

+0

「検索」ボタンで検索条件を指定します。私は100万のレコードが検索されていると言いますが、おそらく500〜10,000のユニークな値を持つ複数のインデックスが日付範囲とともにあります。 AutoPostBacksは、日付範囲に基づいて、リストされたユニークなインデックス値をトリミングします。 –

答えて

6

フィールド(または他の入力コントロール)にAutoPostBack = "true"を設定する理由は、そのコントロールのデータが変更されたときにページをポストバックする - ユーザーがボタンをクリックする必要はありません。フィールドがフォーカスを失ったとき、ページはポストバックを行います。

おそらく私は質問を誤解していますか?ページ/フォームをどのように動作させる必要があるかについて、さらに詳しい情報を提供できますか?

編集:詳細情報、OPのコメントに基づいています。

「通常の」ケースではDropDownList1から何かを選択し、DropDownList1の選択項目に基づいてDropDownList2の値を設定するために自動ポストバックを行います。しかし、ユーザは第2のリストを気にしなくてもよい。彼らが "検索"をクリックした場合は、ボタンをクリックしてautopostbackを中止して(すでに進行中)、新しいポストバックを開始する必要があります。

残念ながら、どのバージョンのASP.NETでも、既に進行中のポストバック(クライアント側のコードからではなく)を「中止」する機能はないと思います。したがって、上記の動作を実装するには、標準のASP.NETポストバック動作以外の処理を行う必要があります。

  • DropDownList2の内容を取得するためにAJAXとJSを使用してください。そのAjax呼び出しが進行中にユーザーが検索をクリックすると、ページはすぐにポストバックされます。
  • ページ内に可能なすべてのDropDownList2データをJSON形式で保存します。純粋にクライアント側JSを使用して、List1が変更されたときにList2に移入します。ユーザーが「検索」をクリックすると、ページはすぐにポストバックされます。可能なList2エントリのプールの大きさに応じて、ページサイズが膨大になって実行不能になることがあります。
  • List1が選択を変更したときに、クライアント側JSを使用して検索ボタンを無効にします。オートポストバック(List2を満たす)が完了するまで、ユーザーは「検索」をクリックすることができません。

+2

私はここで同意します。 @ ebyrobのコードは、彼らが何をしようとしているのか少し混乱しています。ユーザーがボタンをクリックすると思ったら、これらのオートポストバックをすべてリッピングすることを強くお勧めします。 – NotMe

+0

Chrisと同意 – SMK

+0

主な用途は「検索」ボタンが付いた検索条件です。検索条件はかなり複雑で、いくつかのフィールドは、フィールド間のデータベース関係に基づいて他のフィールドのオプションを変更します。私はAutoPostBackを使用して、ユーザーが検索ボタンを押す前に条件を変更しました。 –

3

クライアント側は、より対話的にすると、すべてのそのビューステートを送信してページを再描画減らすために、私はミックスに少しjqueryのを追加します。それはあなたが提案しているもののようなものを可能にします。 jqueryはasp.net MVCフレームワークを同梱しているので、asp.netでそれを使用することには恥じません。

ここでは、私が望むと思うものを示すjqueryを使用した簡単な例を示します。 aspxファイル内

まず、jQueryライブラリへの参照を追加。私は Googleコンテンツ配信ネットワークを使用しているため、このファイルをVSプロジェクトに追加することさえできません。 次に、ボタン以外のすべてのサーバーコントロールから自動ポストバック参照を取り出します。そのポストバックをやり続けるには、ある時点で通常のポストバックが必要であると思われ、他のすべてのコントロールはサーバー側の応答を得るためにajaxを使用しているからです。

私はこれらの修正とあなたの例のページを使用して開始:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="temp.aspx.cs" Inherits="temp" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Untitled Page</title> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script> 
</head> 
<body> 
<script type="text/javascript"> 
    $(document).ready(function() { 
     // Establish where the output goes. 
     var outputObject = $("#<%=TextBox2.ClientID %>"); 

     // create a function to do an ajax postback 
     function doAjaxPostback(sender, value) { 
      $.ajax({ 
       type: "POST", 
       url: "temp2.aspx", 
       data: "id=" + sender.attr("id") + "&value=" + value, 
       success: function (data) { outputObject.append("<br />" + data) } 
      }); 
     } 

     // Use jquery to wire up the event handler. We use the ClientID property in case these 
     // elements get embeded in some other server control container later. 
     $("#<%=TextBox1.ClientID %>").keyup(function (event) { doAjaxPostback($(this), $(this).val()); }); 
     $("#<%=TextBox1.ClientID %>").change(function (event) { doAjaxPostback($(this), $(this).val()); }); 
     $("#<%=ListBox1.ClientID %>").change(function (event) { doAjaxPostback($(this), $(this).val()); }); 

     // Use a plain html button tag for ajax only. The server control button gets rendered as 
     // a submit button which requires it to be handled a little differently. 
     $("#PlainButton").click(function (event) { doAjaxPostback($(this), $(this).attr("value")); event.preventDefault(); }); 
    }); 
</script> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:TextBox ID="TextBox1" runat="server" ></asp:TextBox> 
     <asp:Button ID="Button1" runat="server" OnClick="PostBack" Text="Button" /><br /> 
     <button id="PlainButton" value="Plain Old Button">Ajax Only, No postback</button> 
     <br /> 
     <asp:ListBox ID="ListBox1" runat="server" > 
      <asp:ListItem>value1</asp:ListItem> 
      <asp:ListItem>value2</asp:ListItem> 
     </asp:ListBox> 
     <br /> 
     <br /> 
     Events Fired:<br /> 
     <asp:TextBox ID="TextBox2" runat="server" Height="159px" TextMode="MultiLine" Width="438px"></asp:TextBox> 

     </div> 
    </form> 
</body> 
</html> 

次にコードのために、我々はAjaxのようなものに対して定期的にポストバックを取得するときに我々が報告できるように、私は小さな変更を加えたの後ろに:

 protected void PostBack(object sender, System.EventArgs e) 
     { 
      this.TextBox2.Text += "\n\nGot an asp.net postback\n\n" 
       + string.Format("PostBack for - {0}\n", ((System.Web.UI.Control)sender).ID); 
     } 

さて、あまりにも気にならないようにしようとしていましたが、私は2番目のページtemp2.​​aspxを作成しましたが、aspxファイルだけを残しました。裏:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace WebApplication1 
{ 
    public partial class temp2 : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      string id = string.Empty; 
      string value = string.Empty; 
      Response.Clear(); 

      if (Request.Form == null || Request.Form.Count < 1) 
      { 
       Response.Write("I got nothin'"); 
       Response.Flush(); 
       Response.End(); 
       return; 
      } 

      id = Request.Form["id"]; 
      value = Request.Form["value"]; 

      Response.Write(string.Format("\nevent from: {0}; value={1}",id,value)); 
      Response.Flush(); 
      Response.End(); 
     } 
    } 
} 

私がやったことは明らかだったという通知は、フラッシュ、書き込みと応答我々は呼び出し元に送られたいので、テキストのみを終了します。受信したRequest.Formに特定のフィールドなどが含まれていない場合、応答をクリアまたはフラッシュしないajax関数からの呼び出しであるかどうかを確認するために、元の一時ページのpage_loadにファンシーなものこれを別のページとして行うことで、コードを簡素化したいと考えました。これはまた、可能性を開く。

は、それはそれでカナダと米国を持っており、それが変更されたとき、あなたは適切な値に州/都道府県ドロップダウンを移入するためにデータを送り返すしたいダウンあなたが国のドロップを持っていると言います。私はtemp2.​​aspxで行ったように独自のページにルックアップコードを置くことで、そのようなサービスが必要なアプリケーション内のすべてのページから呼び出すことができます。

幸運にも、自分のコードを理解できない場合は教えてください。

関連する問題