长话短说,我正在做一个考试申请,作为我实习的一部分。我目前在候选控制台模块上,该模块负责显示每个部分的问题并收集回复。响应收集基于提供的问题类型。如果问题是多项选择,候选控制台将使用(自定义)单选按钮的组框显示它。例如 - :
如果问题是多选,则候选控制台使用(自定义)复选框的组框显示它。例如 - :
我已经能够在IRC的帮助下成功实施MCQ响应收集。但是,遵循相同的逻辑,我在实施MSQ响应收集方面遇到了绊脚石。
//This is in the QuestionDisplay class.
//MCQ
public void AddOption_mcq(string optionText, bool arg, int QNo, int option)
{
CustomRadio rb = new CustomRadio();
rb.Text = optionText;
rb.Location = new Point(3, 40 + grbOptions.Controls.Count * 30);
rb.AutoSize = true;
rb.Checked = arg;
rb.QuestionNumber = QNo;
rb.optionId = option;
rb.CheckedChanged += delegate(Object sender, System.EventArgs e)
{
temp = sender as CustomRadio;
if (!ResponseMCQ.ContainsKey(QNo)) //First time question is marked, ResponseMCQ is a <int,ButtonBase> dict.
{
ResponseMCQ.Add(QNo, temp);
}
else
ResponseMCQ[QNo] = temp; //All other times
};
grbOptions.Controls.Add(rb); //grbOptions is a groupbox control.
}
//MSQ
public void AddOption_msq(string optionText, bool arg, int QNo, int option)
{
CustomChecks cb = new CustomChecks();
cb.Text = optionText;
cb.Location = new Point(3, 40 + grbOptions.Controls.Count * 30);
cb.AutoSize = true;
cb.Checked = arg;
cb.QuestionNumber = QNo;
cb.optionId = option;
cb.CheckedChanged += delegate(Object sender, System.EventArgs e)
{
temp = sender as CustomChecks;
if(MSQs.Any())
foreach (CustomChecks C in MSQs) //Clear elements from List if on a different question
{
if (C.QuestionNumber != ((CustomChecks)temp).QuestionNumber)
{
IsDifferent = true;
break;
}
}
if (IsDifferent == true)
{
MSQs.Clear();
IsDifferent = false;
}
if(!MSQs.Any(x => x.Text.Equals(optionText))) //Check if the checkbox already exists in the List
MSQs.Add(temp);
if (!ResponseMSQ.ContainsKey(QNo)) //First time the question is marked
{
ResponseMSQ.Add(QNo, MSQs);
}
else
ResponseMSQ[QNo] = MSQs; //All other times
};
grbOptions.Controls.Add(cb);
if (MSQs.Any())
{
foreach (CustomChecks C in MSQs)
{
foreach (CustomChecks D in grbOptions.Controls)
{
if (D.Text.Equals(C.Text))
{
D.Checked = C.Checked;
}
}
}
}
}
//In the main project, this is how I collect MCQ responses -:
temp = questionDisplay1.GetResponse; //questionDisplay1 is a QuestionDisplay object and GetResponse is a ButtonBase object, used to temporarily store the clicked radio button(CustomRadio object).
//MCQResponse is a Dictionary<int, ButtonBase> which stores <QuestionNumber, CustomRadio>.
if (QuesTypes[i].Equals("MCQ"))
{
if (questionDisplay1.MCQResponse.TryGetValue(i, out temp) && questionDisplay1.MCQResponse[i].Text.Equals(s))
{
questionDisplay1.AddOption_mcq(s, true, i, optionId);
}
else
questionDisplay1.AddOption_mcq(s, false, i, optionId);
}
MCQResponse
和MSQResponse
分别属于Dictionary<int, ButtonBase>
和Dictionary<int, List<ButtonBase>>
类型。它们根据QuestionNumber:Object mapping存储数据,其中Object可以是CustomRadio
或CustomChecks
。
对于MCQ,我使用临时ButtonBase对象temp
来存储CustomRadio对象(CheckedChanged事件)。这是第一次标记问题,检查字典。如果不存在,则添加该条目。对于所有其他时间,只需编辑条目。
现在对于MSQ来说,我正试图遵循类似的逻辑,但我正在搞砸某个地方。我使用临时List对象MSQs
来存储多个CustomChecks响应。在第一个if的情况下,如果我遇到一个与我单击复选框的问题不同的问题,我会清除列表。接下来,我检查列表中是否已存在该复选框。如果不存在,我添加它。最后,我使用与MCQ响应集合中类似的逻辑。
为了正确显示CustomChecks元素,添加了最后的foreach
循环。我应该为此目的使用MSQResponse,但我无法弄清楚如何。以下是我面临的主要问题 - :
MSQResponse
。我没有正确使用它。必须有一种更有效的方法来使用此词典收集MSQ响应。任何帮助将不胜感激!
所以,我尝试了James Holderness给出的方法。代码如下 - :
public void AddOption_msq(string optionText, bool arg, int QNo, int option)
{
CustomChecks cb = new CustomChecks();
cb.Text = optionText;
cb.Location = new Point(3, 40 + grbOptions.Controls.Count * 30);
cb.AutoSize = true;
cb.Checked = arg;
cb.QuestionNumber = QNo;
cb.optionId = option;
cb.CheckedChanged += delegate(Object sender, System.EventArgs e)
{
temp = sender as CustomChecks;
if (!ResponseMSQ.ContainsKey(QNo))
{
// First time, add an empty list
ResponseMSQ.Add(QNo, new List<ButtonBase>());
}
if (!ResponseMSQ[QNo].Any(x => x.Text.Equals(optionText))) //Check if the checkbox already exists in the List
{
ResponseMSQ[QNo].Add(temp);
}
if (((CustomChecks)temp).Checked == false) //Removing the checkbox if deselected
{
foreach (CustomChecks C in ResponseMSQ[QNo])
if (C.Text.Equals(temp.Text))
{
ResponseMSQ[QNo].Remove(C);
break;
}
}
};
grbOptions.Controls.Add(cb);
if (ResponseMSQ.ContainsKey(QNo) && ResponseMSQ[QNo].Any()) //For persistently displaying the proper checked state.
{
foreach (CustomChecks C in ResponseMSQ[QNo])
{
foreach (CustomChecks D in grbOptions.Controls)
{
if (D.Text.Equals(C.Text))
{
D.Checked = C.Checked;
}
}
}
}
}
这很有效。我调试了以检查 - :
foreach
,复选框的状态正在正确显示。现在剩下的唯一问题是关于双foreach
的运行时间,但这个解决方案有效。如果有人知道比一次迭代两个列表更好的方法,他们可以在评论中发布它。再次感谢!
答案 0 :(得分:1)
我的C#/ .NET有点生疏,但是你的MSQ CheckedChanged
委托会不会更容易做这样的事情:
temp = sender as CustomChecks;
if (!ResponseMSQ.ContainsKey(QNo))
{
// First time, add an empty list
ResponseMSQ.Add(QNo, new List<ButtonBase>());
}
// At this point you're guaranteed there's something in the dictionary
// for your QNo, even if it's just an empty list.
if (!ResponseMSQ[QNo].Any(x => x.Text.Equals(optionText)))
{
// If the checkbox isn't already in the list, then add it
ResponseMSQ[QNo].Add(temp);
}
在MCQ和MSQ案例中,您永远不会从这些词典中删除任何内容。某人是否永远不可能改变他们的回应?