Format De thi

This commit is contained in:
Nguyễn Thái Phong 2025-10-08 08:59:07 +07:00
parent a6c93d8371
commit 277177a476
15 changed files with 178 additions and 201 deletions

Binary file not shown.

View File

@ -6,53 +6,25 @@
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|E:\\QuizMaster\\QuizMaster\\form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form1.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}|Form"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\form1.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form1.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\response\\questionoption.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:response\\questionoption.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\response\\question.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:response\\question.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\form2.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form2.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\service\\datautil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:service\\datautil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\form2.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form2.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\form1.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:form1.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\dbhelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:dbhelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\response\\categoryinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:response\\categoryinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\service\\excelvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:service\\excelvalidator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\service\\executeexcelservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:service\\executeexcelservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|e:\\quizmaster\\quizmaster\\service\\datautil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{582DBFA6-720D-44B4-B48C-909F4DD98783}|QuizMaster.csproj|solutionrelative:service\\datautil.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@ -72,7 +44,7 @@
"RelativeDocumentMoniker": "Form1.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Form1.cs",
"RelativeToolTip": "Form1.cs",
"ViewState": "AQIAAMcDAAAAAAAAAAAQwNkDAAAAAAAA",
"ViewState": "AQIAAKoDAAAAAAAAAAAuwLMDAAAzAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-26T01:54:54.164Z",
"IsPinned": true,
@ -80,13 +52,13 @@
},
{
"$type": "Document",
"DocumentIndex": 5,
"DocumentIndex": 1,
"Title": "Form2.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Form2.cs",
"RelativeDocumentMoniker": "Form2.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Form2.cs",
"RelativeToolTip": "Form2.cs",
"ViewState": "AQIAABMAAAAAAAAAAAAQwBEAAAAlAAAA",
"ViewState": "AQIAADoAAAAAAAAAAAAkwFwAAABOAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-02T06:28:48.666Z",
"IsPinned": true
@ -109,134 +81,51 @@
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "Form1.cs [Design]",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Form1.cs",
"RelativeDocumentMoniker": "Form1.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Form1.cs [Design]",
"RelativeToolTip": "Form1.cs [Design]",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-03T07:36:07.359Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"DocumentIndex": 5,
"Title": "DataUtil.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Service\\DataUtil.cs",
"RelativeDocumentMoniker": "Service\\DataUtil.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Service\\DataUtil.cs",
"RelativeToolTip": "Service\\DataUtil.cs",
"ViewState": "AQIAABwAAAAAAAAAAAAQwBAAAAAgAAAA",
"ViewState": "AQIAAC4BAAAAAAAAAAAAAEABAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-29T01:45:12.308Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "Question.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Response\\Question.cs",
"RelativeDocumentMoniker": "Response\\Question.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Response\\Question.cs",
"RelativeToolTip": "Response\\Question.cs",
"ViewState": "AQIAAA4AAAAAAAAAAAAAwA0AAAAjAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-01T08:27:57.656Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "QuestionOption.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Response\\QuestionOption.cs",
"RelativeDocumentMoniker": "Response\\QuestionOption.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Response\\QuestionOption.cs",
"RelativeToolTip": "Response\\QuestionOption.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAoAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-02T07:59:06.439Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "Form1.Designer.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Form1.Designer.cs",
"RelativeDocumentMoniker": "Form1.Designer.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Form1.Designer.cs",
"RelativeToolTip": "Form1.Designer.cs",
"ViewState": "AQIAAGkAAAAAAAAAAAAEwHUAAAAzAAAA",
"ViewState": "AQIAAFEAAAAAAAAAAAArwGMAAAAqAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-09-30T04:14:48.709Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"DocumentIndex": 2,
"Title": "Form2.Designer.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Form2.Designer.cs",
"RelativeDocumentMoniker": "Form2.Designer.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Form2.Designer.cs",
"RelativeToolTip": "Form2.Designer.cs",
"ViewState": "AQIAABAAAAAAAAAAAAAjwBwAAAAoAAAA",
"ViewState": "AQIAACAAAAAAAAAAAAArwDYAAAArAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-02T06:23:49.946Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"DocumentIndex": 4,
"Title": "DbHelper.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\DbHelper.cs",
"RelativeDocumentMoniker": "DbHelper.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\DbHelper.cs",
"RelativeToolTip": "DbHelper.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAACAAAAAAAAAA",
"ViewState": "AQIAADAAAAAAAAAAAAAYwBIAAAAPAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-26T01:35:21.294Z"
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "CategoryInfo.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Response\\CategoryInfo.cs",
"RelativeDocumentMoniker": "Response\\CategoryInfo.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Response\\CategoryInfo.cs",
"RelativeToolTip": "Response\\CategoryInfo.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAQAAAAyAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-01T03:49:31.648Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"Title": "Program.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Program.cs",
"RelativeDocumentMoniker": "Program.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Program.cs",
"RelativeToolTip": "Program.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAABAAAAAlAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-01T06:36:20.125Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "ExcelValidator.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Service\\ExcelValidator.cs",
"RelativeDocumentMoniker": "Service\\ExcelValidator.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Service\\ExcelValidator.cs",
"RelativeToolTip": "Service\\ExcelValidator.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAABYAAAA6AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-28T09:23:05.48Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "ExecuteExcelService.cs",
"DocumentMoniker": "E:\\QuizMaster\\QuizMaster\\Service\\ExecuteExcelService.cs",
"RelativeDocumentMoniker": "Service\\ExecuteExcelService.cs",
"ToolTip": "E:\\QuizMaster\\QuizMaster\\Service\\ExecuteExcelService.cs",
"RelativeToolTip": "Service\\ExecuteExcelService.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAB8AAAA8AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-05-28T07:42:59.847Z"
}
]
}

View File

@ -70,20 +70,20 @@
tabPage1.TabIndex = 0;
tabPage1.Text = "Tải lên bộ câu hỏi";
tabPage1.UseVisualStyleBackColor = true;
tabPage1.Click += tabPage1_Click;
//
// textBox1
//
textBox1.Location = new Point(193, 92);
textBox1.Name = "textBox1";
textBox1.ReadOnly = true;
textBox1.Size = new Size(273, 31);
textBox1.TabIndex = 7;
//
// btnUpload
//
btnUpload.Location = new Point(557, 90);
btnUpload.Location = new Point(579, 92);
btnUpload.Name = "btnUpload";
btnUpload.Size = new Size(112, 34);
btnUpload.Size = new Size(112, 32);
btnUpload.TabIndex = 8;
btnUpload.Text = "Upload";
btnUpload.UseVisualStyleBackColor = true;
@ -91,11 +91,11 @@
//
// BtnOpen
//
BtnOpen.Location = new Point(459, 92);
BtnOpen.Location = new Point(461, 92);
BtnOpen.Name = "BtnOpen";
BtnOpen.Size = new Size(92, 32);
BtnOpen.Size = new Size(112, 32);
BtnOpen.TabIndex = 6;
BtnOpen.Text = "open";
BtnOpen.Text = "Choose File";
BtnOpen.UseVisualStyleBackColor = true;
BtnOpen.Click += btnOpen_Click;
//

View File

@ -43,6 +43,19 @@ namespace QuizMaster
public static int spacing = 40; // Khoảng cách giữa các ComboBox
public static int pointX = 19;
private static readonly Random Rng = new Random();
private static List<T> Shuffle<T>(IEnumerable<T> source)
{
var list = source.ToList();
for (int i = list.Count - 1; i > 0; i--)
{
int j = Rng.Next(i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
return list;
}
//Nút Download
private void button1_Click(object sender, EventArgs e)
{
@ -195,7 +208,6 @@ namespace QuizMaster
tb.Visible = false;
}
}
// ==============================================
isUpdating = false; // Kết thúc cập nhật
}
@ -623,13 +635,17 @@ namespace QuizMaster
this.Cursor = Cursors.Default;
}
}
}
private async Task GenerateSingleQuiz(Dictionary<string, string> lstCategory)
{
string randomCode = Rng.Next(100, 999).ToString();
int number = 1;
StringBuilder result = new StringBuilder();
result.AppendLine($"Mã đề: {randomCode}");
result.AppendLine();
foreach (var category in lstCategory)
{
@ -643,11 +659,11 @@ namespace QuizMaster
{
QuestionId = group.Key.QuestionId,
Question = group.Key.Question,
Options = group.Select(o => new
Options = Shuffle(group.Select(o => new
{
Text = o.Option,
IsCorrect = o.IsCorrect == 1
}).ToList()
}))
})
.OrderBy(g => Guid.NewGuid())
.Take(requestedCount)
@ -672,9 +688,9 @@ namespace QuizMaster
}
result.AppendLine();
}
// Hiển thị kết quả
Form2 frm = new Form2(result.ToString());
frm.MaDe = randomCode;
frm.Text = "ĐỀ TRẮC NHIỆM";
frm.ShowDialog();
}
@ -684,18 +700,22 @@ namespace QuizMaster
{
this.Cursor = Cursors.WaitCursor;
// Tạo mã đề ngẫu nhiên (cùng cho cả 2 form)
string randomCode = Rng.Next(100, 999).ToString();
// Tạo cùng 1 bộ câu hỏi cho cả 2 form
var questionsData = await GenerateQuestionsData(lstCategory);
// Tạo nội dung không có đáp án
string contentWithoutAnswers = CreateQuizContent(questionsData, false);
string contentWithoutAnswers = CreateQuizContent(questionsData, false, randomCode);
// Tạo nội dung có đáp án
string contentWithAnswers = CreateQuizContent(questionsData, true);
string contentWithAnswers = CreateQuizContent(questionsData, true, randomCode);
// Mở 2 Form2
Form2 frmWithoutAnswers = new Form2(contentWithoutAnswers);
Form2 frmWithAnswers = new Form2(contentWithAnswers);
frmWithoutAnswers.MaDe = randomCode;
frmWithAnswers.MaDe = randomCode;
frmWithoutAnswers.Text = "ĐỀ TRẮC NGHIỆM";
frmWithAnswers.Text = "ĐỀ TRẮC NGHIỆM (CÓ ĐÁP ÁN)";
@ -730,11 +750,11 @@ namespace QuizMaster
{
QuestionId = group.Key.QuestionId,
Question = group.Key.Question,
Options = group.Select(o => new
Options = Shuffle(group.Select(o => new
{
Text = o.Option,
IsCorrect = o.IsCorrect == 1
}).ToList()
}))
})
.OrderBy(g => Guid.NewGuid())
.Take(requestedCount)
@ -742,13 +762,16 @@ namespace QuizMaster
allQuestions.AddRange(grouped.Cast<dynamic>());
}
return allQuestions;
}
private string CreateQuizContent(List<dynamic> questionsData, bool includeAnswers)
private string CreateQuizContent(List<dynamic> questionsData, bool includeAnswers, string randomCode)
{
StringBuilder result = new StringBuilder();
result.AppendLine($"Mã đề: {randomCode}");
result.AppendLine();
int questionNumber = 1;
foreach (dynamic question in questionsData)
@ -764,29 +787,22 @@ namespace QuizMaster
if (string.IsNullOrWhiteSpace(option.Text))
continue;
result.AppendLine($" {optionLabel}. {option.Text}");
if (includeAnswers && option.IsCorrect)
{
correctAnswer = optionLabel.ToString();
result.AppendLine($" {optionLabel}.* {option.Text}");
}
else
{
result.AppendLine($" {optionLabel}. {option.Text}");
}
optionLabel++;
}
// Thêm đáp án nếu cần
if (includeAnswers && !string.IsNullOrEmpty(correctAnswer))
{
result.AppendLine($" → Đáp án: {correctAnswer}");
}
result.AppendLine();
questionNumber++;
}
return result.ToString();
}
//-----------------------------------------------------------------------------------------------------------------------------------//
private async Task GenerateMultipleQuizzes(Dictionary<string, string> lstCategory, int numberOfCopies, bool includeAnswers)
{
using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
@ -802,25 +818,26 @@ namespace QuizMaster
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
int filesCreated = 0;
// Dictionary để lưu trữ câu hỏi đã được random cho mỗi copyIndex
var quizQuestionsCache = new Dictionary<int, Dictionary<string, List<dynamic>>>();
var randomCodesCache = new Dictionary<int, string>();
// Tạo các file không có đáp án và cache câu hỏi
for (int copyIndex = 1; copyIndex <= numberOfCopies; copyIndex++)
{
string fileName = Path.Combine(basePath, $"DeThi_{copyIndex:D2}_{timestamp}.docx");
var questionsCache = await CreateSingleQuizFileWithCache(fileName, lstCategory, copyIndex, false);
string randomCode = Rng.Next(100, 999).ToString();
randomCodesCache[copyIndex] = randomCode; // Lưu mã đề để tái sử dụng
string fileName = Path.Combine(basePath, $"DeTracNghiem_{randomCode}_{timestamp}.docx");
var questionsCache = await CreateSingleQuizFileWithCache(fileName, lstCategory, copyIndex, false, randomCode);
quizQuestionsCache[copyIndex] = questionsCache;
filesCreated++;
}
// Tạo các file có đáp án nếu checkbox được tích, sử dụng cache
if (includeAnswers)
{
for (int copyIndex = 1; copyIndex <= numberOfCopies; copyIndex++)
{
string fileName = Path.Combine(basePath, $"DeThi_{copyIndex:D2}_DapAn_{timestamp}.docx");
await CreateSingleQuizFileFromCache(fileName, lstCategory, copyIndex, true, quizQuestionsCache[copyIndex]);
string randomCode = randomCodesCache[copyIndex];
string fileName = Path.Combine(basePath, $"DeTracNghiem_{randomCode}_DapAn_{timestamp}.docx");
await CreateSingleQuizFileFromCache(fileName, lstCategory, copyIndex, true, quizQuestionsCache[copyIndex], randomCode);
filesCreated++;
}
}
@ -837,16 +854,28 @@ namespace QuizMaster
}
}
private async Task<Dictionary<string, List<dynamic>>> CreateSingleQuizFileWithCache(string fileName, Dictionary<string, string> lstCategory, int copyIndex, bool includeAnswers)
private async Task<Dictionary<string, List<dynamic>>> CreateSingleQuizFileWithCache(string fileName, Dictionary<string, string> lstCategory, int copyIndex, bool includeAnswers, string randomCode)
{
var questionsCache = new Dictionary<string, List<dynamic>>();
using (var doc = DocX.Create(fileName))
{
// Tiêu đề đề thi
string title = $"ĐỀ SỐ {copyIndex}";
string title = "ĐỀ TRẮC NGHIỆM";
var titleParagraph = doc.InsertParagraph(title);
titleParagraph.FontSize(16).Bold().Alignment = Alignment.center;
var codeParagraph = doc.InsertParagraph($"Mã đề: {randomCode}");
codeParagraph.FontSize(14).Bold().Alignment = Alignment.center;
string hoTen = "Họ và tên: " + new string('.', 106) ;
string sdt = "Số điện thoại: " + new string('.', 100);
string email = "Email: " + new string('.', 113);
doc.InsertParagraph(hoTen).FontSize(12).SpacingBefore(10);
doc.InsertParagraph(sdt).FontSize(12).SpacingBefore(6);
doc.InsertParagraph(email).FontSize(12).SpacingBefore(6).SpacingAfter(18);
doc.InsertParagraph(new string('_', 75)).Bold().SpacingAfter(6).Alignment = Alignment.center;
doc.InsertParagraph(Environment.NewLine);
int questionNumber = 1;
@ -864,17 +893,16 @@ namespace QuizMaster
{
QuestionId = group.Key.QuestionId,
Question = group.Key.Question,
Options = group.Select(o => new
Options = Shuffle(group.Select(o => new
{
Text = o.Option,
IsCorrect = o.IsCorrect == 1
}).ToList()
}))
})
.OrderBy(g => Guid.NewGuid())
.Take(requestedCount)
.ToList();
// Cache câu hỏi để tái sử dụng
questionsCache[categoryName] = grouped.Cast<dynamic>().ToList();
// Tạo câu hỏi
@ -882,8 +910,8 @@ namespace QuizMaster
{
var questionParagraph = doc.InsertParagraph($"Câu {questionNumber}: {question.Question}");
questionParagraph.FontSize(12).Bold();
questionParagraph.SpacingAfter(12);
// Tạo các lựa chọn
char optionLabel = 'A';
string correctAnswer = "";
@ -892,8 +920,14 @@ namespace QuizMaster
if (string.IsNullOrWhiteSpace(option.Text))
continue;
var optionParagraph = doc.InsertParagraph($" {optionLabel}. {option.Text}");
var optionParagraph = doc.InsertParagraph();
string label = $"{optionLabel}.";
string text = " " + option.Text;
optionParagraph.Append(label).Bold();
optionParagraph.Append(text);
optionParagraph.FontSize(11);
optionParagraph.SpacingAfter(6);
optionLabel++;
}
@ -902,21 +936,26 @@ namespace QuizMaster
questionNumber++;
}
}
string end = new string('_', 20) + " Hết" + new string('_', 20);
doc.InsertParagraph(end).FontSize(12).Bold().SpacingAfter(6).SpacingBefore(18).Alignment = Alignment.center;
doc.Save();
}
return questionsCache;
}
private async Task CreateSingleQuizFileFromCache(string fileName, Dictionary<string, string> lstCategory, int copyIndex, bool includeAnswers, Dictionary<string, List<dynamic>> questionsCache)
private async Task CreateSingleQuizFileFromCache(string fileName, Dictionary<string, string> lstCategory, int copyIndex, bool includeAnswers, Dictionary<string, List<dynamic>> questionsCache, string randomCode)
{
using (var doc = DocX.Create(fileName))
{
// Tiêu đề đề thi
string title = $"ĐỀ SỐ {copyIndex} (CÓ ĐÁP ÁN)";
string title = "ĐỀ TRẮC NGHIỆM (CÓ ĐÁP ÁN)";
var titleParagraph = doc.InsertParagraph(title);
titleParagraph.FontSize(16).Bold().Alignment = Alignment.center;
doc.InsertParagraph(Environment.NewLine);
var codeParagraph = doc.InsertParagraph($"Mã đề: {randomCode}");
codeParagraph.FontSize(14).Bold().Alignment = Alignment.center;
doc.InsertParagraph(new string('_', 75)).Bold().SpacingBefore(6).SpacingAfter(6).Alignment = Alignment.center;
doc.InsertParagraph(Environment.NewLine);
int questionNumber = 1;
foreach (var category in lstCategory)
@ -931,6 +970,7 @@ namespace QuizMaster
{
var questionParagraph = doc.InsertParagraph($"Câu {questionNumber}: {question.Question}");
questionParagraph.FontSize(12).Bold();
questionParagraph.SpacingAfter(12);
// Tạo các lựa chọn
char optionLabel = 'A';
@ -941,19 +981,26 @@ namespace QuizMaster
if (string.IsNullOrWhiteSpace(option.Text))
continue;
var optionParagraph = doc.InsertParagraph($" {optionLabel}. {option.Text}");
optionParagraph.FontSize(11);
// Nếu đáp án đúng, thêm dấu * sau nhãn
string displayLabel = option.IsCorrect ? $"{optionLabel}.*" : $"{optionLabel}.";
var optionParagraph = doc.InsertParagraph();
string label = displayLabel;
string text = " " + option.Text;
optionParagraph.Append(label).Bold();
optionParagraph.Append(text);
optionParagraph.FontSize(11);
optionParagraph.SpacingAfter(6);
if (option.IsCorrect)
{
optionParagraph.FontSize(11).Color(Xceed.Drawing.Color.Red).Bold();
}
optionLabel++;
}
doc.InsertParagraph(Environment.NewLine);
questionNumber++;
}
}
string end = new string('_', 20) + " Hết" + new string('_', 20);
doc.InsertParagraph(end).FontSize(12).Bold().SpacingAfter(6).SpacingBefore(18).Alignment = Alignment.center;
doc.Save();
}
}
@ -976,10 +1023,5 @@ namespace QuizMaster
txtNumberOfCopies.Visible = false;
chkIncludeAnswers.Visible = false;
}
private void tabPage1_Click(object sender, EventArgs e)
{
}
}
}

View File

@ -37,7 +37,7 @@
this.txtResult.Size = new System.Drawing.Size(800, 450);
this.txtResult.TabIndex = 0;
//
//
//btnExoortWord
//
this.btnExportWord.Dock = System.Windows.Forms.DockStyle.Bottom;
this.btnExportWord.Height = 40;

View File

@ -10,12 +10,14 @@ namespace QuizMaster
public partial class Form2 : Form
{
private string _content;
public string MaDe { get; set; }
public Form2(string content)
{
InitializeComponent();
_content = content;
txtResult.Text = content;
}
private void btnExportWord_Click(object sender, EventArgs e)
@ -25,8 +27,7 @@ namespace QuizMaster
saveDialog.Filter = "Word Document|*.docx";
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
// Tạo tên file dựa trên title để tránh trùng lặp
string defaultFileName = this.Text.Contains("CÓ ĐÁP ÁN") ? $"DeCoDapAn_{timestamp}.docx": $"DeKhongDapAn_{timestamp}.docx";
string defaultFileName = this.Text.Contains("CÓ ĐÁP ÁN") ? $"DeTracNhiem_{MaDe}_DapAn_{timestamp}.docx": $"DeTracNhiem_{MaDe}_{timestamp}.docx";
saveDialog.FileName = defaultFileName;
if (saveDialog.ShowDialog() == DialogResult.OK)
@ -36,9 +37,7 @@ namespace QuizMaster
using (var doc = DocX.Create(saveDialog.FileName))
{
doc.InsertParagraph(this.Text)
.FontSize(14).Bold().Alignment = Alignment.center;
doc.InsertParagraph(Environment.NewLine);
.FontSize(16).Bold().Alignment = Alignment.center;
ExportContentWithFormatting(doc, _content);
@ -58,25 +57,72 @@ namespace QuizMaster
private void ExportContentWithFormatting(DocX doc, string content)
{
string[] lines = content.Split('\n');
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line))
string trimmedLine = line.Trim();
if (string.IsNullOrEmpty(trimmedLine))
{
doc.InsertParagraph(Environment.NewLine);
doc.InsertParagraph();
continue;
}
if (line.Trim().StartsWith("Câu ") && line.Contains(":"))
Paragraph paragraph;
if (trimmedLine.StartsWith("Câu ") && trimmedLine.Contains(":"))
{
var paragraph = doc.InsertParagraph(line);
paragraph = doc.InsertParagraph(trimmedLine);
paragraph.FontSize(12).Bold();
paragraph.SpacingAfter(12);
}
else if (trimmedLine.StartsWith("Mã đề:"))
{
if (this.Text.Contains("CÓ ĐÁP ÁN"))
{
var codeParagraph = doc.InsertParagraph($"Mã đề: {MaDe}");
codeParagraph.FontSize(14).Bold().Alignment = Alignment.center;
doc.InsertParagraph(new string('_', 75)).Bold().SpacingBefore(6).SpacingAfter(6).Alignment = Alignment.center;
}
else
{
var codeParagraph = doc.InsertParagraph($"Mã đề: {MaDe}");
codeParagraph.FontSize(14).Bold().Alignment = Alignment.center;
string hoTen = "Họ và tên: " + new string('.', 106);
string sdt = "Số điện thoại: " + new string('.', 100);
string email = "Email: " + new string('.', 113);
doc.InsertParagraph(hoTen).FontSize(12).SpacingBefore(10);
doc.InsertParagraph(sdt).FontSize(12).SpacingBefore(6);
doc.InsertParagraph(email).FontSize(12).SpacingBefore(6).SpacingAfter(18);
doc.InsertParagraph(new string('_', 75)).Bold().SpacingAfter(6).Alignment = Alignment.center;
}
}
else if (trimmedLine.Length > 2 && trimmedLine[1] == '.')
{
paragraph = doc.InsertParagraph();
string label = trimmedLine.Substring(0, 2);
string text = trimmedLine.Substring(2).Trim();
paragraph.Append(label).Bold();
paragraph.Append(" " + text);
paragraph.FontSize(11);
paragraph.SpacingAfter(6);
}
else
{
doc.InsertParagraph(line).FontSize(12);
paragraph = doc.InsertParagraph(trimmedLine);
paragraph.FontSize(11);
}
}
string end = new string('_', 20) + " Hết" + new string('_', 20);
doc.InsertParagraph(end).Bold().FontSize(12).SpacingAfter(6).SpacingBefore(18).Alignment = Alignment.center;
}
}
}