Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
74
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

5. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через прямой доступ к элементу формы

Добавим для двух форм приложения два текстовых поля. Для формы LWP04Main добавим TextBox ( ):

Параметры добавленного текстового поля редактирования таковы:

(Name):

TextBoxMain

Modifiers:

Public

Событие TextChanged текстового поля редактирования TextBoxMain:

private void TextBoxMain_TextChanged(object sender, EventArgs e)

{

dlg.TextBoxChildren.Text = TextBoxMain.Text; // При изменении текста в поле TextBoxMain тоже самое происходит в поле TextBoxChildren

}

Для формы LWP04Children добавим TextBox ( ):

Рис. 5. 1. Расстановка элементов на добавленной форме LWP04Children

Параметры добавленного тектового поля редактирования таковы:

(Name):

TextBoxChildren

Modifiers:

Public

Событие Load формы LWP04Main:

private void LWP04Main_Load(object sender, EventArgs e)

{

dlg.TextBoxChildren.TextChanged += new EventHandler(LWP04Main_Load); // Определяем, что прозизошло изменение текста в TextBoxChildren и вызываем событие Load

TextBoxMain.Text = dlg.TextBoxChildren.Text;

}

Рис. 5. 2. Свойства элемента управления TextBoxMain: значения поля свойства Modifiers

Параметры добавленной кнопки Закрыть:

(Name):

ButtonClose

Text:

Закрыть

Size:

75; 23

Событие Click кнопки ButtonCLose:

private void ButtonClose_Click(object sender, EventArgs e)

{

Close();

}

Компилируем приложение, проверяем работу текстовых полей. При изменении текста у одного (любого) меняется значение во втором:

Рис. 5. 3. Динамическое изменение значений текстовых полей двух форм

Единственны «минус» такого варианта работы с формами, это атрибут public для поля Modifiers элементов управления. То есть этот вариант можно использовать, но безопасность данных в элементе управления в этом случае ставится под сомнение изначально. Потому что этот элемент и все его свойства, поля и данные становятся «видимыми» из любого места приложения. Под «безопасностью» понимаем не взлом приложения, а доступность данных внутри приложения и возможное нарушение согласования типов при манипуляции с переменными. То есть нарушается принцип инкапсуляции. Если приходится открывать то что должно приватным, значит что то не правильно в архитектуре приложения.

Следующие два способа, объединены общими принципами сохранения основ ООП и инкапсуляции. Но в основе лежит одна и также возможность языка C#. Мы попробуем организовать динамическое обновление полей при помощи так называемых делегатов.

6. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через передачу метода в конструктор формы

Создаём новую форму LWP04ChildrenDelegate1 со следующими элементами:

Рис. 6. 1. Расстановка элементов на добавленной форме LWP04ChildrenDelegate1

Параметры формы LWP04ChildrenDelegate1 таковы:

(Name):

LWP04ChildrenDelegate1

Text:

Работа с окнами (C#) :: Подчинённая форма для делегата № 1

Size:

500; 100

FormBorderStyle:

Fixed Dialog

MaximizeBox:

False

MinimizeBox:

False

ShowInTaskbar:

False

Рис. 6. 1. Свойства формы LWP04ChildrenDelegate1: значения поля свойства ShowInTaskbar

Рис. 6. 2. Свойства формы LWP04ChildrenDelegate1: значения поля свойства FormBorderStyle

Здесь также был использован новый элемент управления из коллекции элементов Label: обычный «текст» на форме:

Для элемента Label ключевым свойством является Text.

Параметры добавленного текстового поля редактирования таковы:

(Name):

TextBoxChildrenDelegate1

Событие TextChanged текстового поля редактирования TextBoxChildrenDelegate1:

private void TextBoxChildrenDelegate1_TextChanged(object sender, EventArgs e)

{

Text1 = TextBoxChildrenDelegate1.Text; // Присваиваем переменной обратной передачи значение текстового поля

}

Параметры добавленной кнопки Закрыть:

(Name):

ButtonClose

Text:

Закрыть

Size:

75; 23

Событие Click кнопки ButtonClose:

private void ButtonClose_Click(object sender, EventArgs e)

{

Close();

}

Для формы LWP04Main добавим Button:

Рис. 6. 3. Расстановка элементов на добавленной форме LWP04Main: кнопка Для делегата № 1

Параметры добавленной кнопки таковы:

(Name):

ButtonShowChildrenDelegate1

Text:

Для делегата № 1

Size:

150; 23

ToolTip на Hint:

Передача параметра через метод в конструкторе

Событие Click кнопки ButtonShowChildrenDelegate1:

private void ButtonShowChildrenDelegate1_Click(object sender, EventArgs e)

{

/* Создаём экземпляр класса формы LWP04ChildrenDelegate1, вызывает конструктор

* Вместе с формой создаём экземпляр делегата с вызовом метода TextBoxNewDelegate1() */

LWP04ChildrenDelegate1 D1 = new LWP04ChildrenDelegate1(new NewDelegate1(TextBoxNewDelegate1));

D1.ShowDialog(); // Вызываем модальный диалог нашей формы

MessageBox.Show("Текст который был введён в форме:\n\n" + D1.Text1, D1.Text + " :: Результат выполнения"); // Возвращаем с формы переменную Text1 И показываем её в окошке MessageBox.Show

TextBoxMain.Text = D1.Text1; // Отправляем переменную в поле TextBoxMan

}

Ниже в этом же файле добавляем следующее:

string TextBoxNewDelegate1()

{

// Метод возвращает значение TextBoxMain, нужен для работы делегата

return TextBoxMain.Text;

}

В файле Program.cs ищем:

Application.Run(new LWP04Main());

}

}

Добавляем после:

public delegate string NewDelegate1(); // Создаём делегата № 1

Полный исходный код файла LWP04ChildrenDelegate1.cs (формы) с комментариями:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace LWP04WindowsForms03

{

public partial class LWP04ChildrenDelegate1 : Form

{

private NewDelegate1 D1; // Объявляем экземпляр делегата NewDelegate1

public String Text1; // Объявляем переменную для передачи параметра обратно в главную форму

// Меняем конструктор формы, чтобы он мог узнать какой метод ему был отправлен...

public LWP04ChildrenDelegate1(NewDelegate1 sender)

{

InitializeComponent();

D1 = sender; // ...и кем

}

private void ButtonClose_Click(object sender, EventArgs e)

{

Close(); // Кнопка Закрыть

}

private void LWP04ChildrenDelegate_Load(object sender, EventArgs e)

{

/* Вызываем созданный экземпляр класса NewDelegate1

* После вызова экземпляр вытаскивает из главной формы метод, а точнее переменную TextBoxNewDelegate1

* Далее делегат становится переменной, которую мы отправляем в TextBoxChildren этой формы

* Сама переменная делегата является возвращаемой строкой от TextBoxMain */

TextBoxChildrenDelegate1.Text = D1();

}

private void TextBoxChildren_TextChanged(object sender, EventArgs e)

{

Text1 = TextBoxChildrenDelegate1.Text; // Присваиваем переменной обратной передачи значение текстового поля

}

}

}

Компилируем приложение, проверяем работу текстовых полей второй добавленной формы и главной формы. При изменении текста в главной форме меняется значение в поле вызываемой формы (по нажатию кнопки Для делегата № 1). Изменений значения поля в вызванной форме приводит к обратному эффекту.

Рис. 6. 4. Статическое изменение значений текстовых полей двух форм (до открытия и закрытия формы)