2011-11-05

MonoDevelop - C# создание простого текстового редактора на Gtk

   Вступление
   В этой статье я покажу Вам, как создавать оконные приложения с графическим интерфейсом. Как добавлять на форму элементы управления. И как сделать ГИ функциональным. Все это будет показано на примере создания простого текстового редактора. Этот редактор будет переводить весь текст в верхний регистр, нижний регистр, и сохранять текст в файл. 
   В зависимости от версии MD внешний вид программы может немного не совпадать с вашим, но все это не значительно.

   Шаг 1. Создание проекта
   Откройте MonoDevelop и выберете пункт меню Menu > New Project. В последних версиях MD может быть File > New > Solution. Откроется откроется окно, как это.

Выберите C# и кликните по пиктограмме Gtk# 2.0 Project. Для продолжения нажмите Forward.
   Для открытия дизайнера формы нажмите правой кнопкой мыши по MainWindow во кладке Solution и выберете пункт меню Open. В нижней части окна есть две кнопки для переключения между режимами редактирования формы(Designer) и искходного кода(Source).

   Шаг 2. Создание графического интерфейса
   Все элементы формы должны быть размещены на так называемых зонах (контейнерах) HBox, VBox, Table и т.д. Ниже, будет показано, как размещать элементы легче всего. Если вы хотите изучить Gtk# более глубже, вы можете перейти по следующей ссылке. Вся информация представлена на английском языке.
   Переключаемся в режим Designer в окне MainWindow.cs.

   2.1 Добавление контейнеров
   Изначально форма окна пустая. Наша задача - заполнить ее нужными нам элементами управления. На панели ToolBox есть две группы элементов управления: Containers - это различные элементы прендазначенные для разметки формы под размещение других элементов управления; Widgets - непосредственно элементы упрвления, т.е. кнопки, списки, переключатели и т.п.
   

   Для начала поместим на форму контейнер VBox (Toolbox > Containers).

Теперь верхний контейнер нам нужно разделить на четыре части. Сделаем мы это поместив на него контейнер HBox.
   По умолчанию, этот эелемент делится на три части, для того чтобы добавить еще одно деление жмем правой кнопкой мыши по любой клетке и выбераем пункт hbox1 > Inset After (Insert Before), в нашем случае это не имеет значения.

   2.2. Добавление элементов управления
   С панели Toolbox на первую строку размещаем четыре кнопки (элемент Button), а на вторую текстовое поле (Text View).
   Каждый элемент управления имеет свои свойства, и сейчас мы будем их изменять. 
И так изменим свойства кнопок. Выделяем первую кнопку, открываем панель Properties. Панель свойств делится на две вкладки: Properties - свойства и Signals - события. Первая кнопка будет у нас очищать редактор от текста. Свойство Name сделаем btnClear. Это имя будет использоваться при редактировании исходного кода формы. В группе Button Properties свойство Label меняем на Clear. Этот текст будет отображаться на самой кнопке на форме. Таким же образом делаем остальные кнопки, в результате чего долждны получить следующее: 

   Обращаю внимание на то, что в свойстве Name пробелы не допустимы. В случае с кнопкой Upper Case ее имя можно сделать следующим btnUpperCase.

   Шаг 3. Добавление функциональности.
   Как было видно из предыдущего шага, элементы управления могут реагировать на определенные события. На каждое событие можно написать определенный код, который будет выполняться в результате этого события. Таким образом можно очень гибко запрограммировать поведение программы. Сейчас мы добавим поведение нашему текстовому редактору в зависимости от нажатия на определенную кнопку.
   Выделяем кнопку Clear, открываем панель Toolbox, переходим на вкладку Signals. В группе Button Signals выполняем двойной клик по событию Clicked. Автоматически открывается исходный код формы с редактированием фукнции события нажатика по кнопке. Вы можете увидеть следующее, хотя возможно, что у вас внутри фигурных скобок не будет никакого текста.

protected void OnBtnClearClicked (object sender, System.EventArgs e)
{
      throw new System.NotImplementedException ();
}


Все же, если этот тест у вас есть, то удаляем эту строку, она нам не нужна, и внутри фигурных скобок вписываем следущий текст: textview1.Buffer.Text = "";.
   Если читать строку дословно, то это звучит примерно так: есть элемент textview1 у которого есть свойство Buffer, свойство Buffer в свою очередь имеет свойство Text. Свойству Text присвоено значение "", т.е. пустой строки. 
   Как это работает? Когда мы вводим текст в текстовое поле. Этот текс вносится в так называемы буфер. И весь введенный текст помещается в свойство Text. Нажатием клавиши Clear, пользователь вызывает принудтельное изменение свойства на пустую строку. Таким образом поле для ввода текста очищается. Далее, таким же образом, как изменяли свойства первой кнопки, меняем события других кнопок.
   Что еще важно, чтобы наша кнопка Save могла записывать текс в файл, нам нужно использовать пространство имен ввода\вывода. В первых строках исходного кода формы добавляем строку using System.IO;.
   И в резульате всех действий, мы должны получть что-то похожее на это:

using System;
using Gtk;
using System.IO;

public partial class MainWindow : Gtk.Window
{
public MainWindow () : base (Gtk.WindowType.Toplevel)
{
Build ();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}

protected void OnBtnClearClicked (object sender, System.EventArgs e)
{
textview1.Buffer.Text = "";
}

protected void OnBtnUpperCaseClicked (object sender, System.EventArgs e)
{
textview1.Buffer.Text = textview1.Buffer.Text.ToUpper();
}

protected void OnBtnLowerCaseClicked (object sender, System.EventArgs e)
{
textview1.Buffer.Text = textview1.Buffer.Text.ToLower();
}

protected void OnBtnSaveClicked (object sender, System.EventArgs e)
{
StreamWriter sw = new StreamWriter("Test.txt");
                sw.Write(textview1.Buffer.Text); 
                textview1.Buffer.Text = "Saved to file!";
                sw.Close(); 
}
}


Разберем некоторые строки.
   textview1.Buffer.Text = textview1.Buffer.Text.ToUpper(); На первый взгляд строка может ввести в замешательство. В свойство текста текстового поля помещается тот же текст, что там и есть, только он пропускается через метод ToUpper(), который переводит весь текст в верхний регистр. 
   В событии нажатии кнопки To Lower функция ToLower() переводит весть текст в нижний регистр.
   StreamWriter sw = new StreamWriter("Test.txt"); Класс StreamWriter предназначен для записи текста в файл. Это строка означает создать экзепляр класса под именем sw. Параметр по умолчанию является имя файла "Test.txt". Такое указание имени файла отоносительно. Т.е. файл будет создан рядом с исполнительным файлом приложения. Должен заметит, если такой файл уже существует, то попытка создать новый вызовет ошибку выполнения программы. По этому перед запуском нужно удалить старый текстовый файл. В следующих уроках я покажу, как выполнять операции с файловой системой.
   sw.Write(textview1.Buffer.Text); Здесь к экземпляру sw применяется метод Write, который производит запись текста в файл, указанный при создании объекта.
   textview1.Buffer.Text = "Saved to file!";  Этой строкой пользователь оповещается о выполнении операции. Как можно понять, в текстовое поле просто помещается текст "Saved to file!".
   После выполнения чтения\записи файла поток нужно закрыть, что и делает строка - sw.Close(); 

   Шаг 4. Запуск приложения.
   Вот собственно и все. Жмем на клавиатуре F5, и наслаждаемся плодами наших стараний. Статья переведена и дополнена с сайта MonoDevelop.

К читателю. 
    Я обратил внимание, что эта страница, самая посещаемая. В видусложившихся обстоятельств буду рад отзывам об этой статье, а что более интересно - Ваши предложения на модификацию и улучшение этого текстового редактора.