长话短说,作为实习的一部分,我正在处理应试申请。我目前在候选控制台模块上,该模块负责显示每个部分的问题并收集响应。响应收集基于提供的问题类型。如果问题是多项选择,候选控制台会使用(自定义)单选按钮的组合框来显示它。例如 -:
如果问题是多选,候选控制台使用(自定义)复选框的组框显示它。例如 -:
在 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 映射存储数据,其中 Object 可能是CustomRadio
或CustomChecks
。
对于 MCQ,我使用临时 ButtonBase 对象temp
来存储单击时的 CustomRadio 对象(CheckedChanged 事件)。第一次标记问题时,检查字典。如果不存在,则添加该条目。对于所有其他时间,条目仅被编辑。
现在对于 MSQ,我正在尝试遵循类似的逻辑,但在某个地方搞砸了。我使用一个临时 List 对象MSQs
来存储多个 CustomChecks 响应。在第一种情况下,如果我的问题与单击复选框的问题不同,我会清除列表。接下来,我检查复选框是否尚未出现在列表中。如果不存在,我添加它。最后,我使用与 MCQ 响应收集类似的逻辑。
为了正确显示 CustomChecks 元素,添加了最后的foreach
循环。我应该为此目的使用 MSQResponse,但我无法弄清楚如何。以下是我面临的主要问题-:
- MSQ 响应仅针对一个问题持续显示。如果我在另一个问题中选择复选框,则不会显示以前的复选框。我必须在主项目中构建类似于我为 MCQ 所做的代码,但我无法为此目的弄清楚。
- 的使用
MSQResponse
。我肯定没有正确使用它。必须有一种更有效的方法来使用此字典收集 MSQ 响应。 - MSQ 方法末尾的双 foreach 循环非常昂贵。我听说过 .NET 4 中的 Zip 操作,但我在项目负责人的严格指示下使用 .NET 3.5。它仅用于持久显示的目的,但仅适用于一个问题。如果我能完全取消它,我会很高兴。
任何帮助将不胜感激!
编辑
所以,我尝试了 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;
}
}
}
}
}
这工作得很好。我调试检查是否-:
- 正在存储响应:ResponseMSQ 正在根据需要存储它们。
- 复选框正在按要求显示:由于
foreach
末尾的双精度,复选框的状态正在正确显示。
现在剩下的唯一问题是 double 的运行时间foreach
,但这个解决方案有效。如果有人知道比一次遍历两个列表更好的方法,他们可以在评论中发布。再次感谢!