我正在尝试创建一个动态调查页面。这个想法似乎很简单,但尝试在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的索引。 (所以user-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)
{
}
现在,第一个问题是,在我点击“提交”后,我得到一个页面,其中仅包含问题,而不是带有答案的radiobuttons!经过大量的搜索,我通过强制在页面初始化时发生数据绑定来解决这个问题:
public void Page_Init(Object sender, EventArgs e)
{
Repeater1.DataBind();
}
但是,如果可以在RadioButtonLists上进行双向数据绑定,我仍然完全处于黑暗状态? (我的意思是使用&lt;%#Bind()%&gt;命令。)或者我是否必须编写自己的程序将答案提交回数据库?为了使事情变得更复杂,首次访问时必须将答案插入Answers表中,而在返回访问时,现有行可以更新。
答案 0 :(得分:1)
是的,当我想使用DropDownList绑定时,我发现了类似的问题。我所做的是从您的示例创建一个自定义控件,该控件继承自RadioButtonList。我给它一个名为Value的额外属性。设置此项后,我将编码以通过值设置所选项目。当我调用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>
安德鲁