Проблема с передачей списка и отображения в dataGrid
13.06.2023, 02:59. Показов 364. Ответов 0
Доброго времени суток. Пишу програмку, столкнулся с проблемой записи выбранных ответов пользователя с listBox-а в список по нажатии на кнопку и передачи и отображении его в dataGridView1. Есть форма Certification, на которой происходят действия выбора ответа на определённый вопрос и запись его в список :
| C# | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
| using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Атестація
{
public partial class Certification : Form
{
private List<Question> questions;
private int currentQuestionIndex;
private string attestation;
private data_base dataBase;
private Timer timer;
string startTime;
public Certification(string attestation)
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.Fixed3D;
this.StartPosition = FormStartPosition.CenterScreen;
// Скрыть кнопки формы
this.ControlBox = false;
this.attestation = attestation;
questions = new List<Question>();
currentQuestionIndex = 0;
dataBase = new data_base();
dataBase.openConnection();
// Получение вопросов для выбранной аттестации
string questionQuery = "SELECT Q.Text, A.Text, A.IsCorrect " +
"FROM Questions Q " +
"JOIN Answers A ON Q.Id = A.QuestionId " +
"WHERE Q.AttestationsId = (SELECT Id FROM Attestations WHERE Name = @Attestation)";
SqlCommand questionCommand = new SqlCommand(questionQuery, dataBase.getConnection());
questionCommand.Parameters.AddWithValue("@Attestation", attestation);
using (SqlDataReader questionReader = questionCommand.ExecuteReader())
{
while (questionReader.Read())
{
string questionText = questionReader.GetString(0);
string answerText = questionReader.GetString(1);
bool isCorrect = questionReader.GetBoolean(2);
Question existingQuestion = questions.Find(q => q.Text == questionText);
if (existingQuestion != null)
{
existingQuestion.Answers.Add(answerText);
}
else
{
questions.Add(new Question(questionText, new List<string> { answerText }, isCorrect));
}
}
}
// Получение времени для выбранной аттестации
string timeQuery = "SELECT T.Meaning " +
"FROM Time T " +
"JOIN Attestations A ON T.Id = A.TimeId " +
"WHERE A.Name = @Attestation";
SqlCommand timeCommand = new SqlCommand(timeQuery, dataBase.getConnection());
timeCommand.Parameters.AddWithValue("@Attestation", attestation);
string timeMeaning = timeCommand.ExecuteScalar()?.ToString();
dataBase.closeConnection();
DisplayQuestion();
if (timeMeaning != null)
{
labelTime.Text = timeMeaning;
startTime = timeMeaning;
// Запуск обратного отсчета времени
TimeSpan timeSpan = TimeSpan.Parse(timeMeaning);
timer = new Timer();
timer.Interval = 1000; // Интервал в миллисекундах (1 секунда)
timer.Tick += (sender, e) =>
{
timeSpan = timeSpan.Subtract(TimeSpan.FromSeconds(1));
labelTime.Text = timeSpan.ToString();
if (timeSpan.TotalSeconds <= 0)
{
timer.Stop();
List<(string, string, string)> results = new List<(string, string, string)>();
foreach (Question question in questions)
{
string userAnswer = ""; // Получите выбранный ответ пользователя
string correctAnswer = ""; // Получите правильный ответ из базы данных для данного вопроса
results.Add((question.Text, userAnswer, correctAnswer));
}
MessageBox.Show("Час закінчився. Атестація завершена!");
Results res = new Results(attestation, startTime, labelTime.Text, results);
res.Show();
this.Hide();
}
};
timer.Start();
}
}
private void DisplayQuestion()
{
if (currentQuestionIndex < questions.Count)
{
Question currentQuestion = questions[currentQuestionIndex];
questionLabel.Text = currentQuestion.Text;
answersListBox.Items.Clear();
foreach (string answer in currentQuestion.Answers)
{
answersListBox.Items.Add(answer);
}
answersListBox.IntegralHeight = false;
}
else
{
// Все вопросы пройдены
MessageBox.Show("Тест завершено!");
List<(string, string, string)> results = new List<(string, string, string)>();
foreach (Question question in questions)
{
string userAnswer = ""; // Получите выбранный ответ пользователя
string correctAnswer = ""; // Получите правильный ответ из базы данных для данного вопроса
results.Add((question.Text, userAnswer, correctAnswer));
}
Results res = new Results(attestation, startTime, labelTime.Text, results);
res.Show();
this.Hide();
// Остановка таймера
if (timer != null)
{
timer.Stop();
}
}
}
private void Certification_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
}
}
private void button1_Click(object sender, EventArgs e)
{
if (answersListBox.SelectedItem != null)
{
// Обрабатываем ответ пользователя
string selectedAnswer = answersListBox.SelectedItem.ToString();
// Здесь можно выполнить необходимые действия для обработки ответа
Question currentQuestion = questions[currentQuestionIndex];
currentQuestion.UserAnswer = selectedAnswer;
currentQuestionIndex++;
if (currentQuestionIndex >= questions.Count)
{
// Ответили на последний вопрос
if (timer != null)
{
timer.Stop();
}
MessageBox.Show("Тестування завершено!");
List<(string, string, string)> results = new List<(string, string, string)>();
foreach (Question question in questions)
{
string userAnswer = question.UserAnswer;
string correctAnswer = ""; // Получите правильный ответ из базы данных для данного вопроса
results.Add((question.Text, userAnswer, correctAnswer));
}
Results res = new Results(attestation, startTime, labelTime.Text, results);
res.Show();
this.Hide();
this.Close();
}
else
{
DisplayQuestion();
}
}
else
{
MessageBox.Show("Оберіть варіант відповіді!");
}
}
private void Certification_Load(object sender, EventArgs e)
{
string fullNameValue = Вхід.FullName;
fullName.Text = fullNameValue;
fullName.TextAlign = HorizontalAlignment.Center; // Установка выравнивания текста по центру
fullName.ReadOnly = true; // Установка текстового поля только для чтения
}
}
public class Question
{
public string Text { get; set; }
public List<string> Answers { get; set; }
public bool IsCorrect { get; set; }
public string UserAnswer { get; set; } // Добавленное свойство
public Question(string text, List<string> answers, bool isCorrect)
{
Text = text;
Answers = answers;
IsCorrect = isCorrect;
}
}
} |
|
и также форма Results, куда собственно передаёться список и должен отобразиться в dataGridView1. Но если пользователь не успевает ответить на все вопросы до окончания таймера, выводиться сообщение, текущая форма закрываеться и открываеться форма Results, где колонка "Ваш ответ" пустая полностью. Хотя в ней должно были записаться выбранные ответы пользователя, а на остальные, на которые он не успел ответить и время закончилось, вывести либо пустую строку либо "Ответ отсутствует". Вот код формы Results :
| C# | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
| using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace Атестація
{
public partial class Results : Form
{
private string attestation;
private string endTime;
private List<(string, string, string)> results;
private data_base dataBase;
private string startTime;
public Results(string attestation, string startTime, string endTime, List<(string, string, string)> results)
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.Fixed3D;
this.StartPosition = FormStartPosition.CenterScreen;
this.attestation = attestation;
this.endTime = endTime;
this.results = results;
this.startTime = startTime;
dataBase = new data_base();
dataGridView1.ReadOnly = true;
// Установка режима автоматического изменения размера столбцов для отображения всего содержимого
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
// Установка свойства AutoSizeMode для каждого столбца
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
private string GetCorrectAnswerForQuestion(string question)
{
dataBase.openConnection();
string answerQuery = "SELECT A.Text " +
"FROM Answers A " +
"JOIN Questions Q ON A.QuestionId = Q.Id " +
"WHERE Q.Text = @Question AND A.IsCorrect = 1";
SqlCommand answerCommand = new SqlCommand(answerQuery, dataBase.getConnection());
answerCommand.Parameters.AddWithValue("@Question", question);
string correctAnswer = answerCommand.ExecuteScalar()?.ToString();
dataBase.closeConnection();
return correctAnswer;
}
private void Results_Load_1(object sender, EventArgs e)
{
// Вывод наименования аттестации и времени окончания
attestationLabel.Text = attestation;
endTimeLabel.Text = endTime;
timeLabel.Text = startTime;
// Создание столбцов в DataGridView
dataGridView1.Columns.Add("questionColumn", "Питання");
dataGridView1.Columns.Add("userAnswerColumn", "Ваша відповідь");
dataGridView1.Columns.Add("correctAnswerColumn", "Правильна відповідь");
int correctAnswersCount = 0;
int totalQuestionsCount = results.Count;
// Вывод результатов в DataGridView и подсчет правильных ответов
foreach (var result in results)
{
string question = result.Item1;
string userAnswer = result.Item2;
string correctAnswer = GetCorrectAnswerForQuestion(question);
dataGridView1.Rows.Add(question, userAnswer, correctAnswer);
if (userAnswer == correctAnswer)
{
correctAnswersCount++;
}
}
// Вычисление использованного времени
DateTime startTimeValue = DateTime.Parse(startTime);
DateTime endTimeValue = DateTime.Parse(endTime);
TimeSpan timeUsed = endTimeValue - startTimeValue;
endTimeLabel.Text = timeUsed.ToString(@"hh\:mm\:ss");
// Вычисление процента правильных ответов
double percentage = (double)correctAnswersCount / totalQuestionsCount * 100;
// Вывод количества правильных ответов
trueLabel.Text = $"Вірних відповідей {correctAnswersCount} з {totalQuestionsCount} ({Math.Round(percentage, 1)}%)";
string fullNameValue = Вхід.FullName;
fullName.Text = fullNameValue;
fullName.TextAlign = HorizontalAlignment.Center; // Установка выравнивания текста по центру
fullName.ReadOnly = true; // Установка текстового поля только для чтения
}
private void Results_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing) // Проверяем, является ли причина закрытия формы нажатием на кнопку закрытия формы (крестик)
{
Application.Exit(); // Завершаем работу программы
}
}
}
} |
|
Уточню, что на форме Certification есть listbox по наименованию answersListBox, вопросы выводяться с бд в questionLabel и кнопка button1. Время выводиться в labelTime. На форме Results : dataGridView1 и пару лейблов, но они меня в данном контексте не интересуют.
Добавлено через 2 минуты
Причём если пользователь успевает ответить на все вопросы до окончания таймера, ответив на последний вопрос ( нажал на button ), то все отображается верно
0
|