Я пытаюсь создать страницу динамического обследования. Идея кажется простой, но попытка реализовать ее в ASP.NET вызывает у меня очень разочарование ...Могу ли я динамически сгенерировать динамические списки RadioButtonList()?
Каждый пользователь связан с отдельным списком вопросов (с несколькими вариантами ответов). У меня есть следующие таблицы данных:
Surveys:
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 для ответа. (Таким образом, пользователь-х ответили "всегда" на вопрос-у.)
Вот моя первая версия кода:
<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();
}
Однако я до сих пор полностью в темноте, если это возможно сделать 2-полосные привязки данных на RadioButtonLists? (Я имею в виду команду <% # Bind()%>). Или мне нужно написать собственную процедуру для отправки ответов обратно в базу данных? Чтобы усложнить ситуацию, при первом посещении ответы должны быть вставлены в таблицу «Ответы», а при возврате посещений существующие строки могут быть UPDATEd.
Попытка выяснить, как это использовать. Нужно ли компилировать как DLL и добавлять его в свой набор инструментов? – paulwhit