2009-03-05 47 views
0

我正在尝试创建一个动态调查页面。这个想法似乎很简单,但试图在ASP.NET中实现它让我感到非常沮丧......我可以绑定(双向)动态生成的RadioButtonLists吗?

每个用户都链接到单个(多选)问题列表。我有以下数据表:

调查:

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()%>命令。)或者我必须编写自己的过程来将答案提交回数据库?为了使事情更加复杂,首次访问时,必须将答案插入到Answers表中,而在返回访问时,现有的行可以更新。

回答

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> 

安德鲁

+0

试图找出如何消费这个。我是否需要编译为DLL并将其添加到我的工具箱? – paulwhit 2009-03-20 20:02:42