Файл: Справочник для опытных и как пособие для начинающих программистов. Компактдиск содержит исходные коды примеров из книги.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.01.2024

Просмотров: 934

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
. Далее через щелчок правой кнопкой мыши перейдем к вкладке программного кода (листинг 4.5).

Листинг 4.5. Программа тестирования знаний студента

// Программа тестирует студента по какому-либо предмету обучения using System;

using System.Windows.Forms ;

// Другие директивы using удалены, поскольку они не используются в данной программе

namespace Тестирование

{

public partial class Form1 : Form

{

int СчетВопросов =0; // Счет вопросов

int ПравилОтветов =0; // Количество правильных ответов

int НеПравилОтветов = 0; // Количество неправильных ответов

string[] НеПравилОтветы; // Массив вопросов, на которые даны неправильные ответы
int НомерПравОтвета; // Номер правильного ответа

int ВыбранОтвет; // Номер ответа, выбранный студентом

// Чтобы русские буквы читались корректно, объявляем объект Кодировка

System.Text.Encoding Кодировка = System.Text.Encoding.GetEncoding(1251);

System.IO.StreamReader Читатель;

public Form1()

{

InitializeComponent(); button1.Text = "Следующий вопрос"; button2.Text = "Выход";

// Подписка на событие изменение состояния

// переключателей RadioButton:

radioButton1.CheckedChanged +=

new System.EventHandler(ИзмСостПерекл); radioButton2.CheckedChanged +=

new System.EventHandler(ИзмСостПерекл); radioButton3.CheckedChanged +=

new System.EventHandler(ИзмСостПерекл); НачалоТеста();

}

void НачалоТеста()

{

Try

{ // Создание экземпляра StreamReader для чтения из файла

Читатель = new System.IO.

StreamReader(System.IO.Directory.GetCurrentDirectory() + @"\test.txt", Кодировка);

this.Text = Читатель.ReadLine(); // Название предмета

// Обнуление всех счетчиков:

СчетВопросов = 0; ПравилОтветов = 0; НеПравилОтветов = 0;

НеПравилОтветы = new string[100];

}

catch (Exception Ситуация)

{ // Отчет о всех ошибках

MessageBox.Show(Ситуация.Message, "Ошибка",

MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

ЧитатьСледВопрос();

}

void ЧитатьСледВопрос()

{

Label1.Text = Читатель.ReadLine();

// Считывание вариантов ответа:

radioButton1.Text = Читатель.ReadLine();

radioButton2.Text = Читатель.ReadLine();

radioButton3.Text = Читатель.ReadLine();

// Выясняем, какой ответ - правильный:

НомерПравОтвета = int.Parse(Читатель.ReadLine());

// Переводим все переключатели в состояние "выключено":

radioButton1.Checked = false; radioButton2.Checked = false;

radioButton3.Checked = false;

// Первая кнопка не активна, пока студент не выберет вариант ответа

Button1.Enabled = false;

СчетВопросов = СчетВопросов +1; // Проверка, конец ли файла:

if (Читатель.EndOfStream == true) button1.Text = "Завершить";

}

private void ИзмСостПерекл(object sender, EventArgs e)

{ // Кнопка "Следующий вопрос" становится активной, и ей передаем фокус

Button1.Enabled = true; button1.Focus ();

RadioButton Переключатель = (RadioButton)sender;


string tmp = Переключатель.Name;

// Выясняем номер ответа, выбранный студентом:

ВыбранОтвет = int.Parse(tmp.Substring(11));

}

private void button1_Click(object sender, EventArgs e)

{ // Щелчок на кнопке

// "Следующий вопрос/Завершить/Начать тестирование снач".

// Счет правильных ответов:

if (ВыбранОтвет == НомерПравОтвета)

ПравилОтветов = ПравилОтветов + 1;

if (ВыбранОтвет != НомерПравОтвета)

{ // Счет неправильных ответов:

НеПравилОтветов = НеПравилОтветов + 1;

// Запоминаем вопросы с неправильными ответами:

НеПравилОтветы[НеПравилОтветов] = label1.Text;

}

if (button1.Text == "Начать тестирование сначала")

{

buttonl.Text = "Следующий вопрос";

// Переключатели становятся видимыми, доступными для выбора:

radioButtonl.Visible = true; radioButton2.Visible = true;

radioButton3 .Visible = true;

// Переход к началу файла

НачалоТеста(); return;

}

if (button1.Text == "Завершить")

{

Читатель.Close(); // Закрываем текстовый файл

// Переключатели делаем невидимыми:

radioButton1.Visible = false; radioButton2.Visible = false;

radioButton3.Visible = false;

// Формируем оценку за тест:

Label1.Text = string.Format("Тестирование завершено.\n" +

"Правильных ответов: {0} из {1}.\n" +

"Оценка в пятибалльной системе: {2:F2}.", ПравилОтветов,
СчетВопросов, (ПравилОтветов * 5F) / СчетВопросов);

// 5F - это максимальная оценка

Button1.Text = "Начать тестирование сначала";

// Вывод вопросов, на которые Вы дали неправильный ответ

string Str = "СПИСОК ВОПРОСОВ, НА КОТОРЫЕ ВЫ ДАЛИ " +

"НЕПРАВИЛЬНЫЙ ОТВЕТ:\n\n";

for (int i = 1; i <= НеПравилОтветов; i++)

Str = Str + НеПравилОтветы!i] + "\n";

// Если есть неправильные ответы, то вывести через MessageBox

// список соответствующих вопросов:

if (НеПравилОтветов != 0)

MessageBox.Show(Str, "Тестирование завершено");

}

if (button1.Text == "Следующий вопрос") ЧитатьСледВопрос();

}

private void button2_Click(object sender, EventArgs e)

{ // Щелчок на кнопке "Выход"

this.Close ();

}

}

}

}

В начале программы объявляем переменные, которые должны быть "видны" из всех процедур класса Form1. Сразу после выполнения процедуры InitializeComponent организуем подписку на событие "изменение состояния пе­реключателей" RadioButton одной процедурой ИзмСостПерекл. В данной програм­ме изменение состояния любого из трех переключателей будем обрабатывать од­ной процедурой ИзмСостПерекл.

Далее в процедуре НачалоТеста открываем файл test.txt, в котором содержится непосредственно тест, и читаем первую строку с названием предмета или темы, подлежащей тестированию. При этом обнуляем счетчик всех вопросов и счетчики вопросов

, на которые студент дал правильные и неправильные ответы. Затем вы­зываем процедуру ЧитатьСледВопрос, которая читает очередной вопрос, варианты ответов на него и номер варианта правильного ответа. Тут же проверяем, не дос­тигнут ли конец читаемого программой файла. Если достигнут, то меняем надпись на первой кнопке на "Завершить". В данной программе надпись на первой кнопке является как бы флагом, который указывает, по какой ветви в программе следует передавать управление.

При выборе студентом того или иного варианта испытуемый может сколь угодно раз щелкать на разных переключателях, пока не выберет окончательно ва­риант ответа. Программа будет фиксировать выбранный вариант только на этапе Щелчка на кнопке Следующий вопрос. В процедуре обработки события "измене­ние состояния переключателей" выясняем, какой из вариантов ответа выбрал сту­дент, но делаем вывод, правильно ли ответил студент или нет, только при обработ­ке события "щелчок" на первой кнопке.

В процедуре обработки события щелчок на первой кнопке ведем счет правильных и неправильных ответов, а также запоминаем в строковый массив вопросы, на которые студент дал неверный ответ. Если достигнут конец файла и надпись на кнопке стала "Завершить", то закрываем текстовый файл, все переключатели делаем невидимыми (уже выбирать нечего) и формируем оценку за прохождение теста, а также через MessageBox выводим список вопросов, на которые испытуемый дал ошибочный ответ.

Фрагмент работы тестирующей программы представлен на рис. 4.5.

На рис. 4.6 показан финальный фрагмент работы тестирующей программы, где выведено обоснование оценки тестирования со списком вопросов, на которые сту­дент ответил неправильно.



Рис. 4.5. Интерфейс тестирующей программы



Рис. 4.6. Финальный фрагмент работы программы

Вы можете совершенствовать данную программу. Например, можно добавить элемент управления Timer, чтобы ограничить время сдачи теста. Убедиться в работоспособности программы можно, открыв решение Тестирование.sin в папке Тестирование.

Пример 27. Простой RTF-редактор

Читателю, вероятно, известно, что Visual С# 2010 имеет элемент управления RichTextBox (форматированное текстовое поле), так же как и предыдущие версия
Visual С#. Этот элемент управления позволяет осуществлять форматирование текста в стандарте RTF(один из форматов MS Word). В формате RTF в текст вводят ся специальные коды форматирования, несущие информацию о гарнитуре, разме pax шрифтов, стилях символов и абзацев, выравнивании и других возможностях форматирования.

Напишем очень простой RTF-редактор, который читает как RTF-файлы, так и обычные текстовые файлы в кодировке Windows 1251, но сохраняет файлы на диск в любом случае в формате RTF. Для этой цели перенесем из панели элементов управления Toolbox элементы управления RichTextBox, меню MenuStrip, SaveFileDialog и OpenFileDialog. В выпадающем меню Файл предусмотрим такие пункты меню, как показано на рис. 4.7: Открыть в формате RTF, Открыть в формате win1251, Сохранить в формате RTF и Выход. Текст программы приве­ден в листинге 4.6.

Листинг 4.6. Простой RTF-редактор

//программа простейшего RTF-редактора using System;

using System.Windows.Forms;

// Другие директивы using удалены, поскольку они не используются в данной программе

namespace RTF_edit

{

public partial class Forml : Form

{

public Form1()

{

InitializeComponent();

base.Text = "Простой RTF-редактор"; richTextBoxl.Clear();

openFileDialog1.FileName = @"c:\Text2.txt";

saveFileDialog1.Filter = "Файлы RTF (*.RTF)|*.RTF";

// Подписка на обработку двух событий одной процедурой: this.oткpытьBФopмaтeRTFToolStripMenuItem.Click += new System.

EventHandler(this.ОТКРЫТЬ);

this. oткpытьBФopмaтeWinl251ToolStripMenuItem.Click += new System.

EventHandler(this.ОТКРЫТЬ);

}

private void ОТКРЫТЬ(object sender, EventArgs e)

{ // Процедура обработки событий открытия файла в двух разных форматах.

// Выясняем, в каком формате открыть файл:

ToolStripMenuItem t = (ToolStripMenuItem)sender;

string format = t.Text; // - читаем надпись на пункте меню

try

{ // Открыть в каком-либо формате:

if (format == "Открыть в формате RTF")

{

openFileDialog1.Filter = "Файлы RTF (*.RTF)|*.RTF";

openFileDialog1.ShowDialog();

if (openFileDialog1.FileName == null) return;

richTextBox1.LoadFile(openFileDialog1.FileName);

}

if (format == "Открыть в формате Winl251")

{

openFileDialog1.Filter = "Текстовые файлы (*.txt)|*.txt" ;

openFileDialog1.ShowDialog();

if (openFileDialog1.FileName == null) return;

richTextBox1.LoadFile(openFileDialog1.FileName,

RichTextBoxStreamType. PlainText) ;

}

richTextBox1.Modified = false;

}

catch (System.IO.FileNotFoundException Exc)

{

MessageBox.Show(Exc.Message + "\nНет такого файла", "Ошибка”,

MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

catch (Exception Exc)

{ // Отчет о других ошибках

MessageBox.Show(Exc.Message, "Ошибка",

MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

}

private void coxpaнитьBФopмaтeRTFToolStripMenuItem_Click(

object sender, EventArgs e)

{


saveFileDialog1.FileName = openFileDialog1.FileName;

if (saveFileDialog1.ShowDialog() == DialogResult.OK) Запись();

}

void Запись()

{

try

{

richTextBox1.SaveFile(saveFileDialog1.FileName);

richTextBox1.Modified = false;

}

catch (Exception Exc)

{ // Отчет обо всех возможных ошибках:

MessageBox.Show(Exc.Message, "Ошибка",

MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

}

}

private void ВыходToolStripMenuItem_Click (object sender, EventArgs e)

{

this.Close() ;

}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

if (richTextBox1.Modified == false) return;

// Если текст модифицирован, то выясняем, записывать ли файл?

DialogResult МВох = MessageBox.Show(

"Текст был изменен. \nСохранить изменения?",

"Простой редактор", MessageBoxButtons.YesNoCancel,

MessageBoxIcon.Exclamation);

// YES - диалог; NO - выход; CANCEL - редактирование

if (МВох == DialogResult.No) return;

if (MBox == DialogResult.Cancel) e.Cancel = true;

if (MBox == DialogResult.Yes)

{

if (saveFileDialog1.ShowDialog() == DialogResult.OK)

{ Запись(); return; }

else e.Cancel = true; // Передумал выходить из ПГМ

} // - DialogResult.Yes

}

}

}

Структура программы аналогична программе простого текстового редактора, описанного в предыдущем разделе. Сразу после выполнения процедуры InitializeComponent задаем начальные значения некоторым переменным (см. текст программы). Здесь же выполняем подписку на обработку одной процедурой открыть двух событий — выбор пунктов меню Открыть в формате RTF и От­крыть в формате Win1251. Подробно особенности обработки событий, создавае­мых разными объектами, обсуждены нами в примерах 17, 18 и др. (см. главу 3). Из этих примеров читатели знают, что сведения об объекте, создавшем событие, нахо­дятся в объектной переменной sender. Какой пункт меню указал пользователь, можно узнать, конвертировав переменную sender в объект t класса ToolStripMenuItem. В таком случае мы можем прочитать в свойстве Text название пункта меню, которое выбрал пользователь. Таким образом, в строковую переменную format попадает или строка "Открыть в формате RTF", или строка "Открыть в Формате Winl251". Метод LoadFile объекта richTextBox1 загружает либо файл в Формате RTF, либо файл в обычном текстовом формате. Перехватчик ошибок catch сообщает пользователю либо о том, что такого файла нет, либо если пользо­ватель использует пункт меню Открыть в формате RTF для открытия текстового файла, он получает сообщение "Недопустимый формат файла".

Сохранение файла (рис. 4.7) выполняется также с использованием стандартного диалога SaveFileDialog. Непосредственное сохранение файла удобнее всего поднять в отдельной процедуре Запись(), поскольку эту процедуру необходимо вызывать также при выходе из программы, когда в документе имеются несохраненные изменения