Изграждане на графичен потребителски интерфейс с Windows Forms



страница10/16
Дата27.09.2016
Размер1.09 Mb.
#10985
1   ...   6   7   8   9   10   11   12   13   ...   16

MDI приложения


MDI (Multiple Document Interface) приложенията поддържат работа с няколко документа едновременно, като всеки документ се показва в свой собствен прозорец, разположен във вътрешността на главния прозорец.

MDI контейнери (MDI parents)


MDI контейнерите са форми, които съдържат други форми. За да укажем, че една форма е MDI контейнер, задаваме на нейното свойство IsMdiContainer стойност true. Тези форми обикновено имат меню Window за смяна на активната форма (на свойството му MdiList е зададена стойност true).

MDI форми (MDI children)


MDI формите се съдържат в контейнер-формата. За да укажем, че една форма е MDI форма, задаваме на свойство MdiParent=<контейнер>, къде­то контейнер е MDI контейнер.

Създаване на многодокументов текстов редактор – пример


С настоящия пример ще демонстрираме изграждане на многодокументов текстов редактор със средствата на Windows Forms и Visual Studio .NET. Редакторът трябва да може да създава, редактира, зарежда и записва текстови доку­менти (файлове) и да позволява работа едновременно с много документи в отделни MDI прозорци.

Чрез примерния текстов редактор ще демонстрираме употребата на някои от Windows Forms контролите, които разгледахме: менюта (MainMenu, MenuItem), ленти с инструменти (ToolBar, ImageList, ToolBarButton) и статус ленти (StatusBar, StatusBarPanel). Ще покажем как се създават приложения, работещи в MDI режим. Ще демонстрираме работата с диалога за избор на файл.

Ето стъпките за изграждането на нашия текстов редактор:


  1. Стартираме VS.NET и създаваме нов Windows Forms проект.

  2. Взимаме от ToolBox на VS.NET едно MainMenu, един ToolBar, един ImageList, един StatusBar и един OpenFileDialog и ги поставяме в главната форма. Задаваме подходящи имена на поставените компо­ненти. Препоръчително е името на една контрола да съдържа нейното предназначе­ние и тип (или префикс, указващ типа). В нашия случай подходящи имена са: MenuMainForm, ToolBarMainForm, ImageListToolBar, StatusBarMainForm и OpenFileDialog.

  3. Задаваме за филтър на OpenFileDialog контролата стойността “Text files (*.txt)|*.txt”. Този филтър указва търсена само на текстови файлове (.txt).

  4. Дефинираме File и Window менюта в главното меню (засега ще ги оставим празни, без елементи в тях).

  5. Задаваме на главната форма име MainForm и заглавие "Text Editor Demo". Променяме и името на файла от Form1.cs на MainForm.cs. На картинката по-долу е показано как изглежда разработваното прило­жение в този момент.

  6. Преди да дефинираме бутоните в лентата с инструменти трябва да заредим подходящи иконки за тях в ImageList контролата. Трябват ни иконка за нов файл, за отваряне на файл и за запис на файл. Можем да използваме стандартните иконки, идващи с VS.NET. Те се намират в директория: C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Graphics\bitmaps\OffCtlBr\Small\Color (при стандартна инсталация на Visual Studio .NET).



  1. От редактора за свойствата на компонентите избираме свойството Images на ImageList контролата. Появява се Image Collection Editor, от който можем да добавим иконки в списъка. Добавяме подходящи иконки за нов файл, за отваряне на файл и за запис на файл:



  1. За да дефинираме бутоните в лентата с инструменти първо свързваме ImageList свойството на ToolBar контролата с ImageList компонентата, която заредихме с иконки в предната стъпка. След това използваме свойството Buttons на поставената във формата ToolBar контрола за да дефинираме бутоните. За редакция на това свойство се използва ToolBarButton Collection Editor, който се появява при опит за редактиране на свойството Buttons:

Добавяме три бутона (за нов файл, за отваряне на файл и за запис на файл) и задаваме за всеки от тях подходящо име и ImageIndex, който го свързва с неговата иконка от ImageList контролата. В този момент в лентата с инструменти се появяват трите бутона с иконки върху тях:





  1. Статус лентата ще разделим на две части. В лявата част ще показваме информация за извършените от приложението действия, а в дясната – номера на реда в текущия файл. За целта задаваме на статус лентата ShowPanels=true и добавяме в нея два панела (чрез свойството Panels). Задаваме им имената StatusBarPanelInfo и StatusBarPanelLine и им настройваме размерите:

Статус лентата добива следния вид:





  1. За да направим главната форма MDI форма, й задаваме IsMdiContainer=true.

  2. Създаваме елементите на главното меню File: New, Open, Save и Exit. За да създадем разделител преди елемента Exit, задаваме на съответната MenuItem контрола Text="-". За Window менюто задава­ме MdiList=true за да показва списък от MDI прозорците в главната форма. За елементите на менюто избираме подходящи имена (напри­мер MenuItemFileNew, MenuItemFileOpen, ...). Задава­ме и подходящи бързи клавиши (shortcuts) за често използваните команди чрез свойството Shortcut на MenuItem контролата – [Ctrl+N] за File | New, [Ctrl+O] за File | Open, [Ctrl+S] за File | Save и [Alt-F4] за File | Exit. Ето как изглежда главното меню в този момент:

Цялата форма на приложението добива следния вид:





  1. Вече имаме главната форма. Остава да добавим формата за редак­тиране на файловете и да реализираме логиката на прило­жението. Започваме от дефиниране на събитията за елементите от менюто. С двойно щракване върху елемент от менюто, VS.NET ни дава въз­можност да напишем кода за обработка на събитието му Click:

private void MenuItemFileNew_Click(object sender,

System.EventArgs e)

{

CreateNewFile();



}
private void MenuItemFileOpen_Click(object sender,

System.EventArgs e)

{

OpenExistingFile();



}
private void MenuItemFileSave_Click(object sender,

System.EventArgs e)

{

SaveCurrentFile();



}
private void MenuItemFileExit_Click(object sender,

System.EventArgs e)

{

Close();


}

Методите CreateNewFile(), OpenExistingFile() и SaveCurrentFile() ще разгледаме след малко.

  1. Дефинираме и обработчик на събитието натискане на бутон от лентата с инструменти:

private void ToolBarMainForm_ButtonClick(object sender,

System.Windows.Forms.ToolBarButtonClickEventArgs e)

{

if (e.Button == ToolBarButtonNew)



{

CreateNewFile();

}

else if (e.Button == ToolBarButtonOpen)



{

OpenExistingFile();

}

else if (e.Button == ToolBarButtonSave)



{

SaveCurrentFile();

}

}


Понеже контролата ToolBar не предоставя отделни събития за всеки от бутоните си, трябва да се прихване събитието й ButtonClick и да се проверява за кой от бутоните се отнася то (чрез свойството Button на ToolBarButtonClickEventArgs параметъра).

  1. Остава да дефинираме формата за редакция на документ и да реализираме логиката за създаване, редактиране, зареждане и за­писване на документи. Създаваме нова форма (File | Add New Item … | Windows Form). Сменяме й името на EditorForm, а името на нейния файл – на EditorForm.cs. Тази форма ще служи за редак­ция на документите. Тя ще се използва като подчинена MDI форма.

  2. Добавяме RichTextBox контрола в новата форма. Тя ще служи за редакция на текста на документите. Използваме RichTextBox вмес­то TextBox, защото RichTextBox позволява работа с по-големи доку­менти и осигурява по-голяма гъвкавост. Задаваме Dock=Fill за RichTextBox контролата и й сменяме името на EditorRichTextBox. Ето как изглежда формата след всички тези действия:



  1. Дефинираме в новата форма поле mFileName, което ще съхранява името на текущия отворен файл или null, ако текущият файл няма име (например ако е нов файл):

    private string mFileName = null;

  2. Поставяме в новата форма един SaveFileDialog. Ще го ползваме при запис на файла, който е зареден в RichTextBox контро­лата. Задаваме му филтър „Text files (*.txt)|*.txt”.

  3. Дефинираме няколко метода, които реализират логиката по отваря­не на нов документ, зареждане на файл и записване на файл, както и помощен метод за обновяване на статус лентата:

public void CreateNewFile()

{

SetStatusBarInfo("Created new file.");



mFileName = null;

this.Text = "Untitled";

}
public void LoadFile(string aFileName)

{

mFileName = aFileName;



this.Text = Path.GetFileName(aFileName);

using (StreamReader reader = File.OpenText(aFileName))

{

string fileContents = reader.ReadToEnd();



RichTextBoxEditor.Text = fileContents;

}

}


public void Save()

{

if (mFileName == null)



{

if (SaveFileDialog.ShowDialog() != DialogResult.OK)

{

return;


}

mFileName = SaveFileDialog.FileName;

this.Text = Path.GetFileName(mFileName);

}
using (StreamWriter writer = new StreamWriter(mFileName))

{

writer.Write(RichTextBoxEditor.Text);



}
SetStatusBarInfo("Saved file: " + mFileName);

}
public void SetStatusBarInfo(string aText)

{

MainForm mainForm = (MainForm) this.MdiParent;



mainForm.SetInfoStatusBar(aText);

}


Създаването на нов документ задава заглавие „Untitled” на формата и установява в null името на файла, свързан с нея. Зареждането на файл става с текстов поток. При зареждане формата запомня пълното име на файла, а за заглавие на формата се задава името на файла без пътя. При запис, ако документът не е свързан с файл, се използва файловия диалог за избор на име на файл, в който да се запише. Ако документът е свързан с файл, той просто се записва. Записът става с текстов поток.

  1. Дефинираме няколко обработчика на събития и няколко помощни метода с цел визуализация на номера на реда в текущия файл:

private void EditorForm_Activated(object sender,

System.EventArgs e)

{

ShowLineNumber();



}
private void RichTextBoxEditor_SelectionChanged(object sender,

System.EventArgs e)

{

ShowLineNumber();



}
public void SetStatusBarLine(string aText)

{

MainForm mainForm = (MainForm) this.MdiParent;



mainForm.SetLineStatusBar(aText);

}
public void ShowLineNumber()

{

int currentPos = EditorRichTextBox.SelectionStart;



int line = RichTextBoxEditor.GetLineFromCharIndex(currentPos);

SetStatusBarLine("Line: " + line);

}


При активиране на формата и при промяна на позицията на курсора приложението изчислява номера на текущия ред в текущия документ и го показва в десния панел на лентата за състоянието. Достъпът до лентата на състоянието става през родителската MDI форма (това е главната форма на прило­жението).

  1. Дефинираме и обработчик на събитието „затваряне на формата”, в който извеждаме информация в статус лентата какво се е случило:

private void EditorForm_Closed(object sender,

System.EventArgs e)

{

if (mFileName != null)



{

SetStatusBarInfo("Closed file: " + mFileName);

}

else


{

SetStatusBarInfo("Closed file.");

}

SetStatusBarLine("");



}

С това формата за редактиране на файлове е готова. Остава само да довършим главната форма и приложението ще е готово.

  1. В главната форма пропуснахме да дефинираме методите за отва­ряне на нов файл, за зареждане на съществуващ файл и за затва­ряне на файл. Ето как можем да ги реализираме:

private void CreateNewFile()

{

EditorForm editorForm = new EditorForm();



editorForm.MdiParent = this;

editorForm.CreateNewFile();

editorForm.Show();

}
private void OpenExistingFile()

{

if (OpenFileDialog.ShowDialog() != DialogResult.OK)



{

return;


}
string fileName = OpenFileDialog.FileName;

EditorForm editorForm = new EditorForm();

try

{

editorForm.LoadFile(fileName);



editorForm.MdiParent = this;

editorForm.Show();

SetInfoStatusBar("Loaded file: " + fileName);

}

catch (IOException)



{

editorForm.Dispose();

MessageBox.Show("Can not load file: " + fileName, "Error");

}

}


private void SaveCurrentFile()

{

EditorForm activeEditorForm =



(EditorForm) this.ActiveMdiChild;

if (activeEditorForm != null)

{

activeEditorForm.Save();



}

}


При създаване и зареждане на файл се създава инстанция на формата за редакция на документи EditorForm и в нея съответно се създава нов документ или се зарежда избрания чрез OpenFileDialog файл, след което тази форма се показва като MDI подчинена в главната.

При записване на текущия документ първо се извлича текущата активна форма (ако има такава) и след това й се извиква методът Save() за записване на отворения в нея документ.



  1. Остана само да дефинираме още няколко обработчика на събития за главната форма и няколко помощни метода, които използваме:

    private void MainForm_Load(object sender, System.EventArgs e)

    {

    SetInfoStatusBar("Application started.");



    }
    public void SetInfoStatusBar(string aText)

    {

    StatusBarPanelInfo.Text = aText;



    }
    public void SetLineStatusBar(string aText)

    {

    StatusBarPanelLine.Text = aText;



    }
    static void Main()

    {

    Application.Run(new MainForm());



    }

  2. Приложението вече е готово и можем да го стартираме и тестваме. Ето как изглежда нашият текстов редактор в действие:





Сподели с приятели:
1   ...   6   7   8   9   10   11   12   13   ...   16




©obuch.info 2024
отнасят до администрацията

    Начална страница