我可以对动态生成的 RadioButtonList 进行数据绑定(2 路)吗?
我正在尝试创建一个动态调查页面。 这个想法看起来很简单,但是尝试在 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 上进行 2 路数据绑定,我仍然完全一无所知? (我的意思是使用 <%# Bind() %> 命令。)或者我是否必须编写自己的过程来将答案提交回数据库? 为了使事情变得更复杂,第一次访问时,必须将答案插入到答案表中,而在返回访问时,可以更新现有行。
I am trying to create a dynamic survey page. The idea seems simple, but trying to implement it in ASP.NET is getting me very frustrated...
Each user is linked to an individual list of (multiple-choice) questions. I have the following data tables:
Surveys:
User | Question | Rank
-------+------------+-----
user-x | question-x | 1
user-x | question-y | 2
user-y | question-z | 1
user-y | question-x | 2
Questions:
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
Answers:
User | Question | Answer
-------+------------+-------
user-x | question-x | 0
user-x | question-y | 2
user-y | question-z | 5
So the answer choices are character-separated strings that need to be expended when databinding, and the answers are stored as a 0-based index to the answer. (So user-x answered "always" on question-y.)
Here is my first version of the code:
<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"/>
and:
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)
{
}
Now, the first problem was that after I click "Submit", I get a page in return which only contains the questions, not the radiobuttons with answers! After lots of searching, I fixed this by forcing the data binding to occur on page initialization:
public void Page_Init(Object sender, EventArgs e)
{
Repeater1.DataBind();
}
However, I am still completely in the dark if it is possible to do a 2-way databinding on the RadioButtonLists? (I mean with a <%# Bind() %> command.) Or do I have to write my own procedure for submitting the answers back to the database? To make things more complicated, on first visit the answers will have to be INSERTed into the Answers table, while on return visits the existing rows can be UPDATEd.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,当我想将 Bind 与 DropDownList 一起使用时,我发现了类似的问题。 我所做的是根据您的示例创建一个自定义控件,该控件继承自 RadioButtonList。 我给它一个额外的属性,称为值。 设置完毕后,我将编写代码以通过值设置所选项目。 当我调用 get 时,我返回实际选择的值,因此本质上您需要一个继承自 RadioButtonList 的自定义类,并为其提供一个额外的属性,
然后我可以轻松使用它:
Andrew
Yes, I have found a similar problem when I want to use Bind with the DropDownList. What I do is create a custom control, from your example, which inherits from a RadioButtonList. I give it one extra property called Value. When this is set I then code to set the selected item through the values. When I call the get I return the actual selected value so in essence you need a custom class which inherits from the RadioButtonList and give it an extra property
I can then easily use this:
Andrew