我正在尝试创建包含多页问题的考试。这些问题是在SQL proc中动态创建的。我的aspx页面中有一个Repeater,其中有一个RadioButtonList,它是在我的代码隐藏中动态创建的。
<asp:Repeater ID="ExamQuestionsRepeater" OnItemDataBound="RepeaterItemEventHandler" runat="server">
<ItemTemplate>
<asp:Label ID="QuestionLabel" runat="server"><b><%# Eval("exm_Question") %></b></asp:Label>
<asp:RadioButtonList ID="QuestionsList" runat="server" RepeatDirection="Vertical">
</asp:RadioButtonList>
</ItemTemplate>
<SeparatorTemplate>
<tr>
<td><hr class="ExamQuestionsSeparatorTemplate" /></td>
</tr>
</SeparatorTemplate>
</asp:Repeater>
后面的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadQuestions();
}
}
private void loadQuestions()
{
DataSet dataSet = getData();
PagedDataSource pagedDS = new PagedDataSource();
pagedDS.DataSource = dataSet.Tables[0].DefaultView;
pagedDS.AllowPaging = true; //indicate that data is paged
pagedDS.PageSize = 10; //number of questions per page
//Edit: I noticed I was setting the page index after I bound the repeater
pagedDS.CurrentPageIndex = CurrentPage;
ExamQuestionsRepeater.DataSource = pagedDS;
ExamQuestionsRepeater.DataBind();
//update previous and next buttons depending on what current page is at
updateButtons();
}
}
我在转发器中使用OnItemDataBound事件来绑定动态单选按钮列表
protected void RepeaterItemEventHandler(object sender, RepeaterItemEventArgs e)
{
int questionA = 2;
int questionB = 3;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
RadioButtonList questionsRadioButtonList = (RadioButtonList)e.Item.FindControl("QuestionsList");
DataRow row = ((DataRowView)e.Item.DataItem).Row;
if (row.ItemArray[questionA] != null && !String.IsNullOrEmpty(row.ItemArray[questionA].ToString()))
{
ListItem item = new ListItem();
item.Text = row.ItemArray[questionA].ToString();
item.Value = "A";
questionsRadioButtonList.Items.Add(item);
}
if (row.ItemArray[questionB] != null && !String.IsNullOrEmpty(row.ItemArray[questionB].ToString()))
{
ListItem item = new ListItem();
item.Text = row.ItemArray[questionB].ToString();
item.Value = "B";
questionsRadioButtonList.Items.Add(item);
}
}
}
protected void NextButton_Click(object sender, EventArgs e)
{
// Set viewstate variable to the next page
CurrentPage += 1;
// Reload control
loadQuestions();
}
protected void PreviousButton_Click(object sender, EventArgs e)
{
// Set viewstate variable to the previous page
CurrentPage -= 1;
// Reload control
loadQuestions();
}
我的问题是,当我移至下一页或单击上一页时,问题列表始终与前10个问题绑定,并且状态也不存储在页面之间。在加载下一个“页面”时,我缺少什么或者需要做什么来加载下10个项目?
编辑:我将下一个项目正确地加载到每个页面上。现在的问题是,每次加载列表时,我的视图状态都没有保存单选按钮的值。使用RepeaterItemEventHandler时会覆盖它吗?我应该检查那种方法吗?
所以我想我误会了如何从控件中加载选定的值。我最终创建了用户答案列表,并将其保存到Session变量中。当我在页面之间加载问题时,我将检查该会话列表中是否存在问题/答案对,然后从那里加载值。我的RepeaterItemEvenHandler现在看起来像这样,并且可以完美地完成技巧:
protected void RepeaterItemEventHandler(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
RadioButtonList questionsRadioButtonList = (RadioButtonList)e.Item.FindControl("QuestionsList");
ExamQuestion exam = (ExamQuestion)e.Item.DataItem);
if (!String.IsNullOrEmpty(exam.exm_AnswerA))
{
ListItem item = new ListItem();
item.Text = exam.exm_AnswerA;
item.Value = "A";
questionsRadioButtonList.Items.Add(item);
}
//loading the rest of the list items for the radiobuttonlist goes here...
//here is where I load the answer into the radio button if it was answered before
if (Session["AnswersList"] == null) throw new Exception("Session variable not set properly: AnswersList");
var answers = (List<UserAnswer>)(Session["AnswersList"]);
if (answers.FindIndex(a => a.QuestionID == exam.exm_ID.ToString()) > -1)
{
questionsRadioButtonList.SelectedValue =
answers.Find(a => a.exm_QuestionID == exam.exm_ID.ToString()).exm_UserAnswer;
}
}
}
这是一个简单易用的教程的链接,如果有人需要这种参考,它可以帮助我创建考试:http://www.asp.net/web-forms/videos/building-20-applications/lesson-12-building-a-quiz-engine-2