0

长话短说,作为实习的一部分,我正在处理应试申请。我目前在候选控制台模块上,该模块负责显示每个部分的问题并收集响应。响应收集基于提供的问题类型。如果问题是多项选择,候选控制台会使用(自定义)单选按钮的组合框来显示它。例如 -:

多选题回应

如果问题是多选,候选控制台使用(自定义)复选框的组框显示它。例如 -:

MSQ 响应

在 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);
}

MCQResponseMSQResponse分别是Dictionary<int, ButtonBase>Dictionary<int, List<ButtonBase>>。它们根据 QuestionNumber:Object 映射存储数据,其中 Object 可能是CustomRadioCustomChecks

对于 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;
                    }
                }
            }
        }
}

这工作得很好。我调试检查是否-:

  1. 正在存储响应:ResponseMSQ 正在根据需要存储它们。
  2. 复选框正在按要求显示:由于foreach末尾的双精度,复选框的状态正在正确显示。

现在剩下的唯一问题是 double 的运行时间foreach,但这个解决方案有效。如果有人知道比一次遍历两个列表更好的方法,他们可以在评论中发布。再次感谢!

4

1 回答 1

1

我的 C#/.NET 有点生疏,但是在您的 MSQCheckedChanged委托中执行以下操作会不会更容易:

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 的情况下,您永远不会从这些字典中删除任何内容。有人永远不可能改变他们的反应吗?

于 2013-05-06T10:40:44.443 回答