检索动态生成控件的SelectedValues
本文关键字:SelectedValues 控件 动态 检索 | 更新日期: 2023-09-27 18:13:09
我正在努力了解如何生成动态控件。我有一个Button1_Clickevent,创建一个CheckBoxList (id=cblAnswers)或一个RadioButtonList (id=rblAnswers)取决于数据库中字段的值。
在Button3_Click事件上,我希望能够从生成的控件中检索选定的值,并将它们与列表listofcorrectanswerid进行比较。如果选择的值与listOfCorrectAnswerIDs中的值完全匹配,我想设置一个变量。
我可以创建控件,但我如何检索Button3_Click中的选定值并将它们与列表listOfCorrectAnswerIDs进行比较?
protected void Button1_Click(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
List<string> listOfAnswerIDs = new List<string>();
List<string> listOfAnswers = new List<string>();
List<string> listOfCorrectAnswerIDs = new List<string>();
try
{
conn.Open();
string cmdText = "SELECT * FROM questions_m WHERE question_id=1";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
reader = cmd.ExecuteReader();
if (reader.Read())
{
lblQuestion.Text = reader["question"].ToString();
if (reader["type"].ToString().Equals("C"))
{
CheckBoxList cblAnswers = new CheckBoxList();
cblAnswers.ID = "cblAnswers";
Page.Form.Controls.Add(cblAnswers);
}
else if (reader["type"].ToString().Equals("R"))
{
RadioButtonList rblAnswers = new RadioButtonList();
rblAnswers.ID = "rblAnswers";
Page.Form.Controls.Add(rblAnswers);
}
ViewState["QuestionID"] = reader["question_id"].ToString();
reader.Close();
string cmdText2 = "SELECT * FROM answers_m WHERE question_id=1";
MySqlCommand cmdAnswers = new MySqlCommand(cmdText2, conn);
reader = cmdAnswers.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answerswer_id"].ToString());
listOfAnswers.Add(reader["answerswer"].ToString());
if (reader["correct"].ToString().Equals("Y"))
{
listOfCorrectAnswerIDs.Add(reader["answerswer_id"].ToString());
}
}
reader.Close();
populateAnswers(listOfAnswers, listOfAnswerIDs);
}
else
{
reader.Close();
lblError.Text = "(no questions found)";
}
ViewState["listOfCorrectAnswerIDs"] = listOfCorrectAnswerIDs;
}
catch
{
lblError.Text = "Database connection error - failed to read records.";
}
finally
{
conn.Close();
}
}
protected void Button3_Click(object sender, EventArgs e)
{
if (((CheckBoxList)this.FindControl("cblAnswers")) != null)
{
List<string> selectedValues = ((CheckBoxList)this.FindControl("cblAnswers")).Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
for (int i = 0; i < selectedValues.Count; i++)
{
lblSelected.Text += selectedValues[i].ToString();
}
}
}
加载问题时,将用答案填充的控件的名称存储在ViewState中,并在按钮单击事件中检索控件名称并将其传递给FindControl()。将结果强制转换为CheckBoxList和RadioButtonList的通用基类型,即ListControl。按钮处理程序可能看起来像这样:
protected void Button3_Click(object sender, EventArgs e)
{
string controlName = ViewState["answerswerControlName"];
ListControl answersControl = (ListControl)this.FindControl(controlName);
if (answersControl != null)
{
List<string> selectedValues = answersControl.Items.Cast<ListItem>()
.Where(li => li.Selected)
.Select(li => li.Value)
.ToList();
List<string> listOfCorrectAnswerIDs = (List<string>)ViewState["listOfCorrectAnswerIDs"];
// check for equivalency
string selectedString = string.Join(",", selectedValues.OrderBy(val => val));
string correctString = string.Join(",", listOfCorrectAnswerIDs.OrderBy(val => val));
bool allAnswersCorrect = selectedString == correctString;
}
}
您没有指定如何比较答案集合,因此在这里我提供了一种简单的方法来检查这些集合是否相等(对值进行排序,转换为逗号分隔的列表,并使用字符串相等)。如果你想要像% correct这样的值,你最好遍历正确答案并检查每个正确答案是否包含在selectedValues
列表中,或者使用LINQ集合操作函数,如.Intersect()
。
这是因为您动态创建这些控件的方式。您是在页面初始化所有控件之后创建它们的,因此在每次回发时都会丢失它们。我建议阅读ASP。. NET页面生命周期。
你有几个选择来完成你的目标。你可以重写CreateChildControls方法,或者重写页面的OnInit方法。这两种方法都能达到同样的效果,但如果使用后者,请记住调用基本的Init
方法。
protected override void CreateChildControls()
{
CreateDynamicControls();
}
protected override void OnInit(EventArgs e)
{
CreateDynamicControls();
base.OnInit(e);
}