0

動的調査ページを作成しようとしています。アイデアは単純に思えますが、ASP.NET で実装しようとすると、非常にイライラします...

各ユーザーは、(多肢選択式) 質問の個々のリストにリンクされています。次のデータテーブルがあります。

アンケート:

User   | Question   | Rank
-------+------------+-----
user-x | question-x |    1
user-x | question-y |    2
user-y | question-z |    1
user-y | question-x |    2

質問:

ID         | Text | Choices
-----------+------+-----------------------
question-x | Foo? | yes|no
question-y | Bar? | never|sometimes|always
question-z | Baz? | 1|2|3|4|5|6|7|8|9|10

答え:

User   | Question   | Answer
-------+------------+-------
user-x | question-x |    0
user-x | question-y |    2
user-y | question-z |    5

したがって、回答の選択肢は、データバインディング時に消費する必要がある文字区切りの文字列であり、回答は回答への 0 ベースのインデックスとして保存されます。(したがって、ユーザー x は質問 y で「常に」と答えました。)

コードの最初のバージョンは次のとおりです。

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:dbconn %>" 
    SelectCommand="
        SELECT Questions.Text AS Question, Questions.Choices, Answers.Answer 
        FROM Questions 
            INNER JOIN Surveys ON Surveys.Question = Questions.ID 
            LEFT OUTER JOIN Answers ON Questions.ID = Answers.Question 
                AND Users.ID = Answers.User 
        WHERE (Surveys.User = @User) 
        ORDER BY Surveys.Rank">
    <SelectParameters>
        <asp:QueryStringParameter Name="User" QueryStringField="id" />
    </SelectParameters>
</asp:SqlDataSource>

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1" 
    onitemdatabound="Repeater1_ItemDataBound">
    <HeaderTemplate><table></HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td><%# Eval("Question") %></td>
            <td><asp:Label runat="server" ID="ChoicesLabel"/></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate></table></FooterTemplate>
</asp:Repeater>

<asp:Button ID="Button1" runat="server" Text="Submit" onclick="Button1_Click"/>

と:

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) 
        return;

    DataRowView row = (DataRowView)e.Item.DataItem;
    RadioButtonList rbl = new RadioButtonList();
    rbl.RepeatDirection = RepeatDirection.Horizontal;
    string[] Choices = row["Choices"].ToString().Split('|');
    for (int n = 0; n < Choices.Length; n++)
    {
        rbl.Items.Add(new ListItem(Choices[n], n.ToString()));
    }
    if (row["Answer"] != DBNull.Value)
        rbl.SelectedIndex = (int)row["Answer"];
    ((Label)e.Item.FindControl("ChoicesLabel")).Controls.Add(rbl);
}

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

ここで、最初の問題は、[送信] をクリックした後、応答のあるラジオボタンではなく、質問のみを含むページが返されることでした。何度も検索した後、ページの初期化時にデータバインディングを強制的に発生させることでこれを修正しました。

public void Page_Init(Object sender, EventArgs e)
{
    Repeater1.DataBind();
}

ただし、RadioButtonLists で双方向のデータバインディングを実行できるかどうかは、まだ完全にわかりません。(つまり、<%# Bind() %> コマンドを使用します。) それとも、回答をデータベースに送信するための独自の手順を作成する必要がありますか? さらに複雑なことに、最初のアクセスでは回答を Answers テーブルに INSERT する必要がありますが、再アクセスでは既存の行を更新できます。

4

1 に答える 1

1

はい、Bind を DropDownList で使用したいときに、同様の問題が見つかりました。私がしていることは、あなたの例から、RadioButtonList から継承するカスタム コントロールを作成することです。Value と呼ばれる追加のプロパティを 1 つ指定します。これが設定されたら、値を使用して選択した項目を設定するコードを作成します。get を呼び出すと、実際に選択された値が返されるため、本質的には、RadioButtonList から継承して追加のプロパティを与えるカスタム クラスが必要です。

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

/// <summary>
/// Summary description for BindingRadioButtonList
/// </summary>
public class BindingRadioButtonList : RadioButtonList
{
    public string Value
    {
        get
        {
            return this.SelectedValue;
        }
        set
        {
            if (this.Items.FindByValue(value) != null)
            {
                this.ClearSelection();
                this.Items.FindByValue(value).Selected = true;
            }
        }
    }

    public BindingRadioButtonList()
    {
        //
        // TODO: Add constructor logic here
        //
    }
}

その後、これを簡単に使用できます。

<cc1:BindingRadioButtonList ID="a1" runat="server" Value='<%#Bind("YourValue")%>'>
</cc1:BindingRadioButtonList>

アンドリュー

于 2009-03-06T11:01:09.570 に答える