2009-03-05 75 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