Отваряне на друга форма в c. Отваряне на втори формуляр и предаване на данни към основния формуляр

Абонирай се
Присъединете се към общността "shango.ru"!
Във връзка с:

Днес искам да говоря за това как да създам проект на Windows Forms в C++ в IDE на Visual Studio 2013 Факт е, че, започвайки с VS 2012, елементът Windows Forms Application беше премахнат от списъка с проекти, които могат да бъдат създадени. Сега говоря за този в C++; можете да създадете такъв проект в C#, като изберете подходящия елемент в секцията за създадени проекти. Фактът обаче, че такъв проект не може да бъде избран от списъка, не означава, че не можете да го създадете сами. Точно за това искам да говоря в тази статия.

Първото нещо, което трябва да направите, е да стартирате Visual Studio. След като VS се стартира, щракнете върху Файл > Нов > Проект

След това ще се отвори прозорец с молба да изберете тип проект. Трябва да изберем подраздела CLR в секцията Visual C++ и да изберем Празен CLR проект.

Когато проектът е създаден, в Solution Explorer щракнете с десния бутон върху създадения проект. В контекстното меню, което се отваря, изберете Добавяне > Създаване на елемент и в менюто, което се отваря, в секцията UI изберете Windows Forms

След като формулярът бъде добавен, изберете файла MyForm.cpp в Solution Explorer. Нов раздел ще се отвори пред вас с един ред код:

#include "MyForm.h"

Трябва да добавим следния код към този файл:

Използване на namespace System; използване на пространство от имена System::Windows::Forms; void Main(масив ^ args) ( Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Project1::MyForm form; Application::Run(%form); )

След това в свойствата на проекта. Изберете подсекция Системараздел Linker и в реда Subsystem от падащото меню изберете Windows (/SUBSYSTEM:WINDOWS) и щракнете върху Apply.

Без да затваряте прозореца със свойства на проекта, отидете в подраздела Разширени и в реда Входна точкание пишем Основени след това натиснете клавиша ДОБРЕ.
Това завършва настройките на проекта. За да редактирате външния вид на формуляра, трябва да отидете в раздела MyForm.h [Designer], като щракнете двукратно върху файла MyForm.h в Solution Explorer.

Въпреки факта, че мнението ми за Visual Studio на Microsoft все още е същото, понякога трябва да направите нещо по него. Ако се примирим с факта, че всъщност пишем не на C++, а на така наречения C++/CLI, работата с познати визуални компоненти няма да е толкова различна от същите среди на Borland. Но може да създаде проблеми в сравнение с Builder. Нека разгледаме 3 типични ситуации на работа с приложение, съдържащо повече от една форма. Примерната среда е безплатна Visual C++ 2010 Express, като се предполага, че основната форма има име по подразбиране Form1.

Пример за конструиране и програмно извикване на формуляр

Този код може да бъде изпълнен например чрез щракване върху бутон в главния формуляр Form1.

Form^form2 = gcnew Form(); Button^ button2 = gcnew Button(); бутон2->Текст = L"OK"; бутон2->Местоположение = Точка(10,10); form2->Text = L"Моят прозорец"; form2->HelpButton = true; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; form2->Controls->Add(button2); form2->ShowDialog();

За да добавите манипулатор на кликване за програмно генериран бутон button2, просто напишете преди последния ред код:

Button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);

Преди методът form2->ShowDialog() или form2->Show() да бъде извикан;

В този случай кодът на манипулатора се намира в текущия модул Form1.h:

Частно: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) ( MessageBox::Show("Here"); )

Извикайте друга форма от основната форма

В менюто изберете Проект - Добавяне на нов елемент - Форма - име Form2

Нека добавим оператор

#include "Form2.h"

преди първото пространство от имена във Form1.h (тоест в самото начало на файла).

Нека включим указател към екземпляра на класа в публичната секция на класа Form1:

Form2^F2;

Нека добавим кода, където трябва да създадем и извикаме втората форма:

F2=gcnewForm2(); F2->Покажи();

За програмно изтриване на втората форма е подходящ следният код:

Изтриване на F2;

Трябва да се отбележи, че указателят съхранява адреса само на една форма, тази, която е създадена последна. Ако последователно създадем няколко формуляра, използвайки този код, само последният ще бъде изтрит. Като алтернатива опитайте масива от форми, описан по-долу.

Нека опишем необходимите данни във формуляра клас Form1 (тук името и пространството от имена на проекта Tabulator, ако е необходимо, заменете със собствените си):

Static const int MAX_FORMS = 100; //Максимален брой форми int FormCount; //Масив от брояч на форми ^F2; //Показател към масив от форми

След това инициализираме данните с помощта на събитието Load на главния формуляр:

FormCount=0; F2 = gcnew масив (MAX_FORMS);

След това внедряваме кода, за да създадем следващия формуляр

Ако (FormCount Покажи(); ) else MessageBox::Show("Твърде много форми!");

и премахването му:

Ако (FormCount) ( изтриване на F2; FormCount--; )

Ако искаме да създаваме дъщерни форми не отделно, а вътре в родителската форма, тогава в свойствата на Form1 трябва да посочим, че е „предшественик“ (задайте свойството IsMdiParent = true) и преди да покажем дъщерната форма, използвайки F2->Show() оператор, маркирайте го като дъщерен Form1:

F2->MdiParent = това;

Извикайте метод на родителска форма от дъщерна форма

Едва ли можем да минем без използването на .cpp файлове, което не е лошо - писането на код в .h файлове обикновено нарушава правилната C система :)

Нека опишем процеса стъпка по стъпка.

1) Има 2 форми - Form1 и Form2, на Form1 има бутон (button1, ще отвори втората форма) и етикет (label1, тук ще променим текста). На Form2 - button1, при щракване текстът в label1 ще се промени.

2) Тъй като трябва да имаме достъп до втория от първия формуляр и от втория до първия, ще възникне проблемът с кръстосаните препратки (когато Form1.h препраща към Form2.h, който от своя страна отново препраща към Form1.h). За да избегнем това, ще преместим кода на първия формуляр (Form1), който ще има достъп до втория формуляр (Form2), от .h файла в .cpp файла. По този начин трябва да създадете файл Form1.cpp.

3) Декларирайте публичен метод Set във Form1.h, така че да можете да промените текста на label1 (кодът може да бъде написан в края на файла, след #pragma endregion):

Public: void Set(String^ text) ( label1->Text = text; )

4) Във файла Form2.h включваме Form1.h (в началото):

#include "Form1.h"

и създайте конструктор, който ще приеме и запази връзка към първия формуляр за по-нататъшна употреба:

Form2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //можете да напишете връзка веднага отдолу: private: Form1^ parentForm;

5) При щракване върху бутона във Form2, ще извикаме метода Set на родителския формуляр:

Частно: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) ( parentForm->Set("hello from form2"); parentForm->Show(); this->Hide(); )

6) Остава да отворите втората форма в първата форма. За да направим това, преместваме манипулатора за щракване на бутон от Form1.h във Form1.cpp, а във файла .h оставяме само неговата декларация.

Въпросът, разгледан в тази статия, е по-вероятно да се отнася до темата за изграждане на архитектура на приложение, а не конкретно до разглеждания проблем. Прехвърлянето на данни от една форма в друга не е никак трудно. За да направите това, достатъчно е да отворите контролата, чиито данни искаме да получим, тоест да я маркирате с публичния модификатор. Освен това е възможен и друг вариант. Например, в първата форма създаваме обект от втората форма, като предаваме препратка към себе си към конструктора, тоест като предаваме препратка към първата от първата форма към втората
SecondForm secondForm = нов SecondForm(this);
Естествено, преди да направите това, трябва да се погрижите да създадете претоварване за конструктора на втората форма.

И този метод е доста често срещан. Въпреки това, със своята простота, той носи много потенциални проблеми, основният от които е нарушаване на принципа на капсулиране. С една дума, втората форма не трябва да знае нищо за съществуването на първата и още повече не трябва да може да й влияе.

Решението на този проблем е съвсем просто. Нека да погледнем директно кода. В дизайнера създаваме основния формуляр (ще се стартира при стартиране на приложението). Да сложим един Текстово поле, ЕтикетИ Бутон.

При натискане на бутона се отваря втората форма и текстът от текстовото поле на основната форма се прехвърля в текстовото поле на втората форма. Първоначално втората форма изглежда така:

Подобно на първия, има същите контроли. Не ни трябва повече. Входната точка на приложението стартира главния формуляр:

Използване на системата; използване на System.Collections.Generic; използване на System.Linq; използване на System.Windows.Forms; пространство от имена From1FormTo2 (статичен клас Program ( // Основната входна точка за приложението. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

Основният код на формуляра изглежда така:

Използване на системата; използване на System.Collections.Generic; използване на System.ComponentModel; използване на System.Data; използване на System.Drawing; използване на System.Linq; използване на System.Text; използване на System.Windows.Forms; пространство от имена From1FormTo2 ( публичен частичен клас MainForm: Form ( //втора форма SecondForm secondForm; //конструктор public MainForm() ( InitializeComponent(); ) //манипулатор на събития за трансфер на данни //от главната форма към втората частна void btn_mainForm_Click(object подател, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData(); ) ) )

Съответно, не забравяйте да свържете бутона към събитието Кликнете. Тук, в главния клас на формуляра, има поле SecondForm secondForm, представляващ втория обект на формата. Когато щракнете върху бутона „Изпращане“, се създава втора форма (извиква се претовареният конструктор, ще го създадем по-късно) и се стартира с помощта на метода ShowDialog(). В този случай този метод е подходящ за нас. Освен това след това задължително проверяваме дали втората форма не е затворена, а е кликнато върху нейния бутон. Ако върху втория формуляр е щракнат върху бутон, тогава първият формуляр трябва да приема данни от втория. Това се случва чрез извикване на метода Връщане на данни ()във втората форма.

Сега най-интересната част е кодът на втората форма:

Използване на системата; използване на System.Collections.Generic; използване на System.ComponentModel; използване на System.Data; използване на System.Drawing; използване на System.Linq; използване на System.Text; използване на System.Windows.Forms; пространство от имена From1FormTo2 ( публичен частичен клас SecondForm: Form ( //претоварен конструктор public SecondForm(string data) ( InitializeComponent(); tb_secondForm.Text = data; ) //манипулатор на събитие за прехвърляне на данни //от втората форма към основната private void btn_secondForm_Click (изпращач на обект, EventArgs e) ( this.DialogResult = DialogResult.OK; ) //публичен метод за достъп //до текстовото поле на този формуляр публичен низ ReturnData() ( return (tb_secondForm.Text.Trim()); ) ) )

Както можете да видите, има едно претоварване на конструктора, което приема тип низ. Не забравяйте, че се опитваме да прехвърлим текст от TextBox. В конструктора компонентите са планирани да бъдат инициализирани и текстът на текстовото поле е зададен на предадената стойност от първия формуляр. След това, като се абонирате за събитието Кликнетеза бутона на втората форма създадохме манипулатор btn_secondForm_Click, който симулира работата на бутона „Ok“ на всеки диалогов прозорец. Така с щракване върху бутона „Изпращане“ (на втората форма) изпълняваме условието

(secondForm .DialogResult == DialogResult .OK)

Първата форма, следователно, извикване на метода secondForm .ReturnData(), задаваме текстовото поле на първата форма на стойността на текстовото поле на втората форма.

Работата на този метод, мисля, вече не изисква обяснение. Той просто връща текста от едно текстово поле, като същевременно го запазва лично.

В резултат на това прехвърлихме данни във втората форма от първата и от втората към първата, без да нарушаваме принципите на капсулиране.

Опитайте да въведете текста „aaa“ в текстовото поле на първия формуляр и щракнете върху бутона. Ще видите този текст в текстовото поле във втората форма, която се отваря. Опитайте да промените текста на „aaa ppp“ и щракнете върху бутона. Ще видите как след затваряне на втората форма този текст ще се появи в текстовото поле на основната форма.

Сега мисля, че ще можете да прехвърляте данни между формуляри по-правилно. В следващата статия ще говорим за това как да го направите в ASP.NET приложения.

Понякога е необходимо да получите достъп до елементите на една форма от друга по време на изпълнение на програмата. Например, има форма Form1, от нея отваряме друга Form2 и сега, работейки във Form2, трябва да имаме достъп до елементите на родителската форма Form1. Намерих няколко начина да направя това.

1-ви метод. Предаване на препратка към публична променлива.

Пространство от имена WindowsApplication1 ( публичен частичен клас Form1: Формуляр ( публичен Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // изпращане връзка към бутона във формата Form2 frm.ShowDialog() ) )

Във Form2 променливата, към която е предадена връзката, сега ще съответства на button1 от Form1

Пространство от имена WindowsApplication1 ( public частичен клас Form2: Form ( public Button but1; // тази променлива ще съдържа връзка към button1 от Form1 public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1. Text = "test"; // промяна на текста на бутона button1 на Form1 ) ) )

2-ри метод. Предаване на връзката към дъщерния формуляр.

Същността е приблизително същата в първия метод. Когато отваряме Form2, ние предаваме в него връзка към елемента, който планираме да променим по-късно.

Пространство на имената WindowsApplication1 ( public partial class Form1: Form ( public Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(this.button1); // предаване на връзка към бутона към формата Form2 frm.ShowDialog() ) )

Сега във Form2 трябва да създадем променлива, която ще съдържа връзка към този бутон и чрез нея ще имаме достъп до бутона на Form1 (редове 5,7,9 и 15).

Пространство от имена WindowsApplication1 ( публичен частичен клас Form2: Form ( private Button but1; // тази променлива ще съдържа връзка към бутона button1 от формата Form1 public Form2(Button but) // получаване на връзка към бутона в променливата but ( but1 = but; // сега but1 ще бъде връзка към button1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1.Text = "test"; // промяна на текста на button1 на Form1) )

3-ти метод. Достъп до цялата родителска форма.

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

Етап 1.Във файл Program.csсъздайте публична променлива f1 (ред 5).

Пространство на имената WindowsApplication1 ( статичен клас Program ( public static Form1 f1; // променлива, която ще съдържа връзка към формуляра Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1( ) ) ) )

Стъпка 2.Отваряне Form1.Designer.csи в него, за елементи, които ще трябва да бъдат достъпни от друга форма, ние променяме частенНа публичен. Например, нека направим button1 на Form1 достъпен за промени.

Public System.Windows.Forms.Button button1; // заменен частен с публичен

Стъпка 3. Когато създаваме Form1, присвояваме на променлива f1 връзка към този формуляр (ред 7)

Пространство от имена WindowsApplication1 ( public partial class Form1: Form ( public Form1() ( Program.f1 = this; // сега f1 ще бъде връзка към формуляра Form1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.ShowDialog();

Стъпка 4.Сега от абсолютно всяка форма или от всеки клас можете да получите достъп до елемента button1, разположен на Form1 по следния начин: Program.f1.button1. Например, нека бутонът на Form2 промени текста на бутона на Form1:

Пространство на имената WindowsApplication1 ( public частичен клас Form2: Form ( public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Program.f1.button1.Text = "test"; // Промяна на текста на бутон за форма Form1 ) ) )



Връщане

×
Присъединете се към общността "shango.ru"!
Във връзка с:
Вече съм абониран за общността „shango.ru“.