Рисующее приложение в версии .NET, страница 13

Она будет вызываться в те моменты, когда пользователь закрывает окно последнего документа и клентская область главного окна становится пустой. Давайте временно переключимся на класс DrawView и введем в него реакцию на событие Closed, которое возникает в момент закрытия child-окна. Для этого переведите фокус в окно DrawView.cs[Design], нажмите в окне его свойств кнопку Events, выберите событие Closed и выполните над ним двойной щелчок. В окне редактора кодов появится заготовка функции обработки события. Измените ее тело так, чтобы в нужные моменты происходил вызов функции DisableItems.

private void DrawView_Closed(object sender, EventArgs e)

{

if (mainWnd.MdiChildren.Length == 1)

mainWnd.DisableItems();

}

Отметим, что исходный пример Scribble (в версии C#) содержит ошибку в этом месте. Там свойство Length проверяется на равенство нулю. Вы можете проверить это, запустив пример, закрыв окно единственного документа и дав команду записи в файл, так как она доступна. Теперь вновь вернемся в окно редактора формы главного окна. Повторим действия по вводу функции обработки другой команды меню File4Open.

¨  Переведите фокус в окно MainWindow.cs[Design], раскройте меню File и выберите первую команду Open,

¨  В окне Properties нажмите кнопку Events, выберите событие Click,

¨  В строке справа выберите имя уже существующей функции обработки MenuItemHandler и нажмите Enter.

Это означает, что в ответ на выбор команды меню Open будет вызвана та же функция MenuItemHandler, что и для команды New, но на сей раз она вызовет функцию Open, которую надо ввести в класс MainWindow.

private void Open()

{

OpenFileDialog dlg = new OpenFileDialog();

dlg.Filter  = "Draw Files (*.img)|*.img|All Files (*.*)|*.*";

dlg.FileName = "";

dlg.DefaultExt = ".img";

dlg.CheckFileExists = true;

dlg.CheckPathExists = true;

DialogResult res = dlg.ShowDialog();

if (res == DialogResult.OK)

{

if (!(dlg.FileName.ToUpper().EndsWith(".IMG")))

MessageBox.Show ("Unexpected file format","Draw",MessageBoxButtons.OK);

else

{

if (ActiveMdiChild == null)

EnableItems();

DrawDoc newDoc = CreateDocument();

newDoc.OpenDocument (dlg.FileName);

}

}

}

Здесь иллюстрируется работа со стандартным диалогом по открытию файлов, который управляется классом OpenFileDialog, производным от абстрактного класса FileDialog. Метод ShowDialog запускает диалог в модальном режиме и возвращает результат в виде перечисления (enum DialogResult). Анализ результата позволяет узнать какую кнопку выбрал пользователь при закрытии диалога. Если это была кнопка OK, то результат диалога (файловый путь в виде переменной типа string) выбирается с помощью свойства FileName. Далее мы пользуемся методами класса string для того, чтобы проверить расширение файла. В случае его совпадения с тем расширением, которое соответствует документам нашего приложения (img), создается новый объект класса DrawDoc и для него вызывается метод чтения данных из файла — OpenDocument. Этот метод необходимо ввести в класс документа.

public void OpenDocument(string fileName)

{

try

{

Stream s = File.Open (fileName, FileMode.Open);

BinaryFormatter fmt = new BinaryFormatter();

lineList = (ArrayList)fmt.Deserialize (s);

s.Close();

}

catch (Exception ex)

{

MessageBox.Show(ex.ToString());

}

}

В библиотеке классов .NET Framework существует множество классов для работы с файлами и данными, два из которых использованы в методе OpenDocument. Абстрактный класс Stream является обобщением любой последовательности байт данных, поступающих из файла, из произвольного устройства ввода-вывода, из межпроцессного коммуникационного канала (inter-process communication pipe), либо из TCP/IP сокета (socket). Вспомогательный класс BinaryFormatter позволяет произвести сериализацию всего графа объектов класса в двоичном формате. В нашем случае — всей коллекции объектов типа ArrayList. Метод Deserialize производит чтение объектов из потока, а метод Serialize — их запись. Сами эти методы определены в интерфейсе IFormatter, который реализуется классом BinaryFormatter. В этот момент вы можете откомпилировать приложение с тем, чтобы устранить возможные ошибки, правда при этом придется временно закомментировать вызовы недостающих функций Close, Save, Print, PrintPreview и Exit.