2

動的に作成された質問とオプションを使用して、asp.net でクイズ コントロールに取り組んでいます。メイン コントロールは基本的に、すべての質問を保持するコンテナです。デザイン ビューでは、ユーザーはカスタム コレクション エディターを使用して質問を追加できます。コレクション エディター リストに質問を追加するたびに、質問タグが生成されます。各質問オブジェクト内には、ラジオボタン コントロールを継承するラベルと多数のオプション オブジェクトがありますこれらの各 Option オブジェクトは、ユーザーが各質問に対して選択できるオプションを順番に表します。

これはすべて機能しますが、各ラジオボタンのチェック済みの値を読み取れるようにしたい部分にいることを除いて。このクイズをページ内に実装して質問を確認したい場合、このページにボタンを配置し、コントロール内にある次の関数を呼び出します。

$

    public String checkQuestions()
    {


        if (questions != null)
        {

            foreach (Question question in questions)
            {

                options = question.readOptions();

                int i = 0;
                foreach (Option option in options)
                {
                    testLabel.Text = option.Checked.ToString(); // test purposes only
                }

            }



        }
       return errors;

    }

ただし、ラジオボタンを選択して送信ボタンをクリックすると、すべてのオプションで Checked 値が常に false になります。基本的に、ポストバック後にチェックされた値が失われ、解決しようとして立ち往生しています。誰かが私を正しい方向に向けることができれば幸いです。

4

1 に答える 1

4

一見すると、私が確認することが2つあります。まず、実装していることを確認してくださいIPostBackDataHandlerLoadPostDataこれには、との 2 つのメソッドを実装する必要がありますRaisePostDataChangedEvent。私の最初の推測では、最初のものはおそらくあなたの問題の原因です。

ポストバックを手動で処理する

LoadPostDatapostDataKey文字列と aを取り、ポストバックの結果として値が変更されたかどうかを示すaを返します。.Net が最初に意図した方法でこれを実装する必要はありません。たとえば、いくつかのラジオ ボタンを保持するコントロールを作成しました (ここでは重要ではないため、単にコントロールにすることはできません)。すべてプロパティによって名前が付けられ、そのために検査されました:NameValueCollection postCollectionboolRadioButtonListstring GroupNamepostCollectionGroupName

public bool LoadPostData(string postDataKey,
    System.Collections.Specialized.NameValueCollection postCollection)
{
    bool oldValue = _isChecked;

    postCollection = HttpContext.Current.Request.Form; // See note below

    _isChecked = (postCollection[this.GroupName] == this.Text);

    return oldValue == _isChecked;
}

postCollectionここでを再定義していることに気付くでしょう。これは、コントロールが気にする必要があると ASP.Net が考えるものpostCollectionに対応する のサブセットのみが含まれているためです。HttpRequest.Formここで複合コントロールも作成しているので、おそらく同じことをしたいと思うでしょう。

これが最初にうまくいかなくても心配しないでください。デバッグ モードでこのメソッドに渡されたものをステップ実行して (または に出力するHttpContext.Trace方が簡単なことがよくあります)、コードが必要なものではない理由を確認する価値があります。

簡単な警告

最後に 1 つ:LoadPostDataは、投稿されたフォームに、コントロールの と一致する名前のフィールドが含まれている場合にのみ呼び出されUniqueIDます。コントロールは複合コントロールであるため、次のように、これを少しカウボーイしたい場合があります。

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);

    writer.WriteBeginTag("input");
    writer.WriteAttribute("type", "hidden");
    writer.WriteAttribute("name", this.UniqueID);
    writer.WriteAttribute("value", "post");
    writer.Write(" />");
}

汚いハックですが、うまくいきます;o)

ビューステートを手動で処理する

ポストバックを手動で処理しても問題が解決しない場合は、コントロールのビューステートをいじる必要がある可能性があります。心配する必要はありません。いくつかの簡単なルールに従えば、見た目ほど怖くはありません。

ビューステートを手動で処理するには、明らかに と という 2 つのメソッドをオーバーライドする必要がありLoadViewStateますSaveViewState。1 つ目はビューステートの を受け取り、もう 1つは同じ構造objectを返します。object永続化が必要なすべての重要なプロパティを保存するために必要な構造を含む何かをオーバーライドして返す場合は、メソッドSaveViewStateで再度インフレートするだけです。LoadViewState

ここで最初の狡猾なトリックが登場します。ビューステートの保存に使用する必要がある特定のデータ型があり、他の型は使用しないでください (他の型は非常に非効率的に格納されるため)。あなたにとっておそらく最も有用なタイプはSystem.Web.UI.PairSystem.Web.UI.Tripletと、古くからの友人であるSystem.Collections.ArrayListSystem.Collections.Hashtableです。ペアとトリプレットは、 type の 2 つまたは 3 つの値を格納するだけobjectです。ArrayLists は事実上List<object>.

あなたの状況では、おそらく(1)ラジオボタンの「チェック状態」を保存するブールフラグのArrayList、または(2)IDまたはインデックスを保存する文字列またはintのArrayListのいずれかを保存する必要があると思いますチェックされたラジオボタン。

前述のコントロールでは、checkedness とTextプロパティを格納するだけでよかったので、メソッドLoadViewStateSaveViewStateメソッドは次のようになりました。

protected override void LoadViewState(object savedState)
{
    Pair state = savedState as Pair;

    if (state != null)
    {
        _isChecked = state.First as Nullable<bool> ?? false;
        this.Text = state.Second as string;
    }
}


protected override object SaveViewState()
{
    return new Pair(_isChecked, this.Text);
}

繰り返しますが、これが初めてうまくいかない場合は、ほとんどの場合、コードをステップ実行するか、Trace に何かをスローする必要があります。重要なのは、viewstate が壊れているか、存在しないなどの場合に備えて、これらのメソッドから例外をスローしないようにすることです。

ビューステートの詳細情報

ビューステートをいじっているときに、ブックマークしておく非常に役立つ記事がいくつかあります。最初のものは、特定のタイプのみをビューステートに保存する必要がある理由 ( ArrayListandHashtableではなくList<T>andを使用するなどDictionary<TKey, TValue>) について説明し、2 つ目は、これらすべてのビューステートが実際にどのように機能するかについての詳細な説明です。

  1. BinaryFormatter に手を出させないでください。
  2. ViewState を真に理解する

これがすべて問題の解決に役立つことを願っています。

于 2010-10-05T16:36:00.150 に答える