4

PhoneInfo.ascx というコントロールを含むページがあります。PhoneInfo は LoadControl() を使用して動的に作成され、次に initControl() 関数が呼び出され、初期化オブジェクトを渡して PhoneInfo 内のいくつかの初期テキスト ボックス値を設定します。

次に、ユーザーはこれらの値を変更し、「submit_click」イベントに接続されているページの送信ボタンを押します。このイベントは、PhoneInfo 内の GetPhone() 関数を呼び出します。返される値には、phoneId 値 (ViewState に保存され、ユーザーによって編集されない) が常に null として返されることを除いて、新しいユーザーが入力した値がすべて含まれます。

ビューステートは、ポストバック全体でユーザーが入力したデータを追跡する責任があると信じているため、ユーザー値がどのように戻ってくるのか理解できませんが、明示的に設定された ViewState["PhoneId"] 値は理解できません! ViewState["PhoneId"] 値を PhoneInfo の page_load イベントに設定すると、ポストバック後に正しく取得されますが、ページが提供する準備が整ったときにのみその値を初期化できるため、これはオプションではありません。

どういうわけかページのライフサイクルを台無しにしているだけだと確信しています。提案や質問は本当に役に立ちます! 以下に、実際のコードを大幅に簡略化したバージョンを含めました。

ページの分離コードを含む

protected void Page_Load(object sender, EventArgs e)
{
    Phone phone = controlToBind as Phone;
    PhoneInfo phoneInfo = (PhoneInfo)LoadControl("phoneInfo.ascx"); //Create phoneInfo control
    phoneInfo.InitControl(phone); //use controlToBind to initialize the new control
    Controls.Add(phoneInfo);
}
protected void submit_click(object sender, EventArgs e)
{
    Phone phone = phoneInfo.GetPhone();
}

PhoneInfo.ascx 分離コード

protected void Page_Load(object sender, EventArgs e)
{
}

public void InitControl(Phone phone)
{
    if (phone != null)
    {
        ViewState["PhoneId"] = phone.Id;
        txt_areaCode.Text = SafeConvert.ToString(phone.AreaCode);
        txt_number.Text =  SafeConvert.ToString(phone.Number);
        ddl_type.SelectedValue = SafeConvert.ToString((int)phone.Type);
    }
}

public Phone GetPhone()
{
    Phone phone = new Phone();
    if ((int)ViewState["PhoneId"] >= 0)
        phone.Id = (int)ViewState["PhoneId"];
        phone.AreaCode = SafeConvert.ToInt(txt_areaCode.Text);
        phone.Number = SafeConvert.ToInt(txt_number.Text);
        phone.Type = (PhoneType)Enum.ToObject(typeof(PhoneType),       SafeConvert.ToInt(ddl_type.SelectedValue));
        return phone;
    }
}
4

4 に答える 4

1

ViewState は、Init イベントと Load イベントの間で管理されます。ポストバックからの値の維持に関心がある場合は、Page_Load の代わりに Page_Init ハンドラーのコードまたは呼び出し関数を使用する必要があります。

ASP.NET ページのライフ サイクルの詳細については、このリンクを参照してください。

http://msdn.microsoft.com/en-us/library/ms178472.aspx

于 2010-03-31T17:41:50.790 に答える
1

回答者のように、SaveViewState中に保存するには遅すぎてViewState変数を設定していたため、この問題が存在すると思いました。ただし、SaveViewState イベントのオーバーライドを追加し、ViewState が保存されるずっと前に ViewState 変数を設定していたことは確かです。あまりにも前に、それが判明しました。

どうやら初期化後、.net は TrackViewState() を実行し、追加した viewState 変数を実際にリッスンし始めます。TrackViewState() が実行される前にこの viewState 値を設定していたので、すべて正常に表示されましたが、SaveViewState 中に値が実際に追加されていませんでした。変数を設定する直前に明示的に TrackViewState() を呼び出すと、すべてが期待どおりに機能しました。

私の最終的な解決策は、初期化を通じて ID 値を保持するプライベート プロパティを割り当て、SaveViewState 中にプロパティ値から viewState 変数を設定することでした。このようにして、明示的に呼び出して物事の流れを台無しにすることなく、TrackViewState が .net によって実行されたことを確認できます。page_load で viewState 値を再読み込みし、それを使用してプロパティの値を設定します。この値は、GetPhone 関数で使用できます。

この記事では、enableViewState について説明します。

private int _id = -1;

protected void Page_Load(object sender, EventArgs e)
{
    if (ViewState["PhoneId"] != null)
    _id = SafeConvert.ToInt(ViewState["PhoneId"]);
}

protected override object SaveViewState()
{
    ViewState["PhoneId"] = _id;
    return base.SaveViewState();
}

public Phone GetPhone()
{
    Phone phone = new Phone();
    phone.Id = _id;
    phone.AreaCode = SafeConvert.ToInt(txt_areaCode.Text);
    phone.Number = SafeConvert.ToInt(txt_number.Text);
    return phone;
}
于 2010-04-01T14:17:37.777 に答える
0

あなたがしていることを正確に行うにInitは、ページのライフサイクルの一部にコントロールをロードする必要があります。

ただし、より簡単に行うには、 に追加してみません<asp:ContentPlaceHolder>か? これでだいぶ楽になると思います。

于 2010-03-31T17:43:32.700 に答える
0

コメントへの回答に基づいて、ページのライフサイクルの一部と、それが投稿およびビューステート データに対して何を意味するかを説明する別の回答をここに追加します。以下は、(開発者向けに)より英語であり、ページのライフサイクルの開始のイベントバージョンについてはありません。

  1. ユーザーがページをリクエスト (リクエスト 1)
  2. ASP.NET は、フィールドの既定値を使用してページを構築します (要求 1)。
  3. Page_Load で、この特別なコントロールをデフォルト値で追加します (リクエスト 1)。
  4. このページをユーザーに送信します (要求 1)
  5. ユーザーがページにデータを投稿する (リクエスト 2)
  6. ASP.NET が ASPX ファイルからページを構築します (要求 2)。
  7. ASP.NET は ViewState データをページに追加します (現時点ではありません) (要求 2)
  8. ASP.NET は投稿データをページに追加します (要求 2)
  9. ASP.NET の実行は、ページ ライフサイクルの読み込みステップに到達し、既定値を使用して特別なコントロールを追加します (要求 2)。
  10. あなたは今、あなたが見ている問題のある状態にいます。

したがって、ここでの問題は、投稿データがページに追加されたときに、動的に読み込まれるコントロールが存在しないことです。追加するときは、デフォルト値を入れます。ASP.NET には、適切なデータを入力する機会がありません。

于 2010-03-31T18:08:22.653 に答える