В прошлой части мы разработали внешнюю оболочку нашего блокнота. В этой части мы напишем код для работы с файлами: научим блокнот создавать, открывать, сохранять, а также печатать текстовые документы.
bool tbChange = false;
string docPath = "";
if (tbChange == true)
{
DialogResult message = MessageBox.Show("Сохранить текущий документ перед созданием нового?", "Создание документа", MessageBoxButtons.YesNoCancel);
if (message == DialogResult.Yes)
{
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
else if (docPath == "")
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
}
else if (message == DialogResult.No)
{
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
}
else
{
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
if (tbChange == true)
{
DialogResult message = MessageBox.Show("Сохранить текущий документ перед открытием нового?", "Открытие документа", MessageBoxButtons.YesNoCancel);
if (message == DialogResult.Yes)
{
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
else if (docPath == "")
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
}
else if (message == DialogResult.No)
{
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
else
{
return;
}
}
else
{
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
}
else
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
}
После этого заходим в класс Program.cs и меняем строку:
Application.Run(new MainForm());
на:
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length >=2)
{
Application.Run(new MainForm(arguments[1]));
}
else
{
Application.Run(new MainForm());
}
Для начала в коде формы MainForm.cs добавим переменную-индикатор, которая будет сообщать о том, что в документе произошли какие-либо изменения. Она потребуется для того, чтобы программа понимала, когда можно просто очистить элемент notebox, а когда нужно сперва предложить сохранить изменения в документе. А также создадим переменную, в которую будем записывать путь открытого документа. Это потребуется для функции сохранения открытого документа. Поэтому в коде формы добавим строки:
string docPath = "";
Примечание. Важно добавить эти строки вне функций, чтобы у всех элементов формы был к ним доступ. Я добавил их сразу после функции инициализации компонентов формы.
Теперь нажмем дважды на textbox и перейдем в обработчик событий изменения текста в элементе notebox. Запишем туда следующую строку:
tbChange = true;
То есть, теперь если текст документа будет как-то изменяться, наша переменная-индикатор изменит свое значение на True.
Теперь добавим на форму следующие элементы:
- printDocument1 (printDocument)
- printDialog1 (printDialog) - в свойствах, в поле "Document" выбираем наш printDocument
- pageSetupDialog1 (pageSetupDialog) - в свойствах, в поле "Document" выбираем наш printDocument
Они понадобятся нам для обеспечения возможности печати документа, а также настройки параметров печатаемых страниц.
Настройки приложения
Чтобы улучшить удобство использования программы, научим её запоминать изменения в интерфейсе, внесенные пользователем. Для этого открываем свойства проекта и переходим на вкладку параметров (Проект-Свойства-Параметры).
В первый столбец заносим имена параметров, во втором выбираем их тип, в четвертом указываем значение по-умолчанию:
- programmName - string - Копирайтер+
- newDocName - string - Новый документ
- statusStripVisible - bool - True
- textTransfer - bool - False
- textFont - System.Drawing.Font - Segoe UI; 9,75pt
- formWidth - int - 640
- formHeight - int - 400
Для того чтобы значения применялись и сохранялись, задействуем 2 события формы MainForm.cs: "Load" (Событие при загрузке формы) и "FormClosing" (Событие после нажатия на кнопку закрытия формы, но до самого закрытия).
Код для события Load:
this.Width = Properties.Settings.Default.formWidth;
this.Height = Properties.Settings.Default.formHeight;
notebox.Font = Properties.Settings.Default.textFont;
if (Properties.Settings.Default.statusStripVisible == true)
{ mViewStatusStrip.CheckState = CheckState.Checked; }
else
{ mViewStatusStrip.CheckState = CheckState.Unchecked; }
if (Properties.Settings.Default.textTransfer == true)
{ mFormatTransfer.CheckState = CheckState.Checked; }
else
{ mFormatTransfer.CheckState = CheckState.Unchecked; }
Код для события Closing:
Properties.Settings.Default.formWidth = this.Width;
Properties.Settings.Default.formHeight = this.Height;
Properties.Settings.Default.textTransfer = notebox.WordWrap;
Properties.Settings.Default.textFont = notebox.Font;
Properties.Settings.Default.statusStripVisible = statusStrip.Visible;
Properties.Settings.Default.Save();
Параметры programmName и newDocName здесь не используются. Они понадобятся далее.
FileWorks.cs
Создаем класс для операций с файлами (FileWork.cs). В него мы поместим все методы для работы с файлами, которые будут применяться в коде не 1 раз: создать, открыть, сохранить, сохранить как.
Прописываем необходимые инструкции:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Windows.Forms;
using System.Text;
Приступаем к созданию методов:
public static void CreateFile(ref TextBox notebox, ref bool tbChange, ref string docPath) // Метод "Создать новый документ"
{
string newDocName = Properties.Settings.Default.newDocName;
string programmName = Properties.Settings.Default.programmName;
notebox.Clear();
docPath = "";
tbChange = false;
MainForm.ActiveForm.Text = newDocName + " — " + programmName;
}
public static void OpenFile(ref TextBox notebox, ref bool tbChange, ref string docPath) // Метод "Открыть документ"
{
string programmName = Properties.Settings.Default.programmName;
OpenFileDialog openDocument = new OpenFileDialog();
openDocument.Title = "Открыть текстовый документ";
openDocument.Filter = "Текстовые файлы (*.txt) |*.txt| Все файлы (*.*)|*.*";
if (openDocument.ShowDialog() == DialogResult.OK)
{
FileStream file = new FileStream(openDocument.FileName, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(file, Encoding.Default);
notebox.Text = reader.ReadToEnd();
reader.Close();
docPath = openDocument.FileName;
tbChange = false;
MainForm.ActiveForm.Text = openDocument.SafeFileName + " — " + programmName;
}
}
public static void SaveFile(ref TextBox notebox, ref bool tbChange, ref string docPath) // Метод "Сохранить документ"
{
FileStream file = new FileStream(docPath, FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(file, Encoding.Default);
writer.Write(notebox.Text);
writer.Close();
tbChange = false;
}
public static void SaveAsFile(ref TextBox notebox, ref bool tbChange, ref string docPath) // Метод "Сохранить документ как..."
{
string programmName = Properties.Settings.Default.programmName;
SaveFileDialog saveAsDocument = new SaveFileDialog();
saveAsDocument.Title = "Сохранить документ как...";
saveAsDocument.FileName = "Текстовый документ";
saveAsDocument.Filter = "Текстовые файлы (*.txt) |*.txt| Все файлы (*.*)|*.*";
if (saveAsDocument.ShowDialog() == DialogResult.OK) //Если пользователь подтвердил сохранение
{
//Создаем файл по пути, выбранному в окне сохранения
FileStream file = new FileStream(saveAsDocument.FileName, FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(file, Encoding.Default);
writer.Write(notebox.Text); //записываем содержимое в файл
writer.Close(); //закрываем поток
tbChange = false;
docPath = saveAsDocument.FileName;
MainForm.ActiveForm.Text = Path.GetFileName(saveAsDocument.FileName) + " — " + programmName;
}
else
{
tbChange = true;
return;
}
}
Теперь можно писать код для самих элементов меню "Файл".
Создать документ
{
DialogResult message = MessageBox.Show("Сохранить текущий документ перед созданием нового?", "Создание документа", MessageBoxButtons.YesNoCancel);
if (message == DialogResult.Yes)
{
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
else if (docPath == "")
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
}
else if (message == DialogResult.No)
{
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
}
else
{
FileWork.CreateFile(ref notebox, ref tbChange, ref docPath);
}
Открыть документ
{
DialogResult message = MessageBox.Show("Сохранить текущий документ перед открытием нового?", "Открытие документа", MessageBoxButtons.YesNoCancel);
if (message == DialogResult.Yes)
{
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
else if (docPath == "")
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
}
else if (message == DialogResult.No)
{
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
else
{
return;
}
}
else
{
FileWork.OpenFile(ref notebox, ref tbChange, ref docPath);
}
Сохранить документ
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
}
else
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
}
Сохранить документ как...
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
Параметры страницы печати
if (pageSetupDialog.ShowDialog() == DialogResult.OK)
{
printDocument.DefaultPageSettings = pageSetupDialog.PageSettings;
}
Печать документа
if (printDialog.ShowDialog() == DialogResult.OK)
{
try
{
printDocument.Print();
}
catch (Exception)
{
MessageBox.Show("Ошибка параметров печати.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
Выход из программы
Application.Exit();
Стоит предусмотреть ситуацию, когда пользователь мог забыть сохранить документ или кнопка закрытия программы и вовсе была нажата случайно. В таком случае, если документ был изменен, но не сохранен - предложим ему сохранить документ перед закрытием. Для этого добавим в событие MainForm.cs "FormClosing" следующий код:
if (tbChange == true)
{
DialogResult message = MessageBox.Show("Сохранить текущий документ перед выходом?", "Выход из программы", MessageBoxButtons.YesNoCancel);
if (message == DialogResult.Yes)
{
if (docPath != "")
{
FileWork.SaveFile(ref notebox, ref tbChange, ref docPath);
Application.Exit();
}
else if (docPath == "")
{
FileWork.SaveAsFile(ref notebox, ref tbChange, ref docPath);
Application.Exit();
}
}
else if (message == DialogResult.Cancel)
{
e.Cancel = true;
}
}
Открытие документов нашим приложением через функцию "Открыть с помощью"
В любой программе, которая создается для использования людьми, должна быть возможность открывать файлы (с которыми работает приложение) через это самое приложение. В частных случаях, когда у приложения файлы с собственным расширением - необходимо работать с реестром и ассоциировать конкретный формат с конкретным приложением.
Мы велосипед не изобретали, наша программа простая и работает с распространенными расширениями (текстовые документы). Поэтому нам будет достаточно указать условие, при выполнении которого приложение (во время открытия через него текстового документа) будет автоматически загружать в себя содержимое файла.
В коде MainForm.cs изменяем код:
public MainForm()
{
InitializeComponent();
}
на:
public MainForm()
{
InitializeComponent();
this.Text = Properties.Settings.Default.newDocName + " - " + Properties.Settings.Default.programmName;
}
public MainForm(string fileName) // Открытие программы документом
{
InitializeComponent();
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
try
{
string programmName = Properties.Settings.Default.programmName;
FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(file, Encoding.Default);
notebox.Text = reader.ReadToEnd();
reader.Close();
docPath = fileName;
tbChange = false;
this.Text = Path.GetFileName(fileName) + " — " + programmName;
notebox.Select(0, 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
После этого заходим в класс Program.cs и меняем строку:
Application.Run(new MainForm());
на:
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length >=2)
{
Application.Run(new MainForm(arguments[1]));
}
else
{
Application.Run(new MainForm());
}
На этом работа с файлами в нашем текстовом редакторе завершена. В следующей части мы напишем код для правки текста в редакторе.