Pagdaragdag ng mga form. Pakikipag-ugnayan sa pagitan ng mga form
Minsan kinakailangan upang ma-access ang mga elemento ng isang form mula sa isa pa sa panahon ng pagpapatupad ng programa. Halimbawa, mayroong isang form na Form1, mula dito ay nagbubukas kami ng isa pang Form2 at ngayon, nagtatrabaho sa Form2, kailangan naming i-access ang mga elemento ng parent form na Form1. Nakakita ako ng ilang paraan para gawin ito.
1st method. Pagpasa ng reference sa isang pampublikong variable.
Namespace WindowsApplication1 ( public partial class Form1: Form ( public Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // send link sa button sa form na Form2 frm.ShowDialog(); ) ) )
Sa Form2, ang variable kung saan naipasa ang link ay tumutugma na ngayon sa button1 mula sa Form1
Namespace WindowsApplication1 ( public partial class Form2: Form ( public Button but1; // this variable will contain a link to button1 from Form1 public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1. Text = "test"; // palitan ang text sa button na button1 ng Form1 ) ) )
ika-2 paraan. Pagpasa ng link sa form ng bata.
Ang kakanyahan ay humigit-kumulang pareho sa 1st na paraan. Kapag binubuksan ang Form2, ipinapasa namin dito ang isang link sa elemento na plano naming baguhin sa ibang pagkakataon.
Namespace WindowsApplication1 ( public partial class Form1: Form ( public Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(this.button1); // ipasa ang isang link sa button sa form na Form2 frm.ShowDialog(); ) ) )
Ngayon sa Form2 kailangan nating gumawa ng variable na maglalaman ng link sa button na ito at sa pamamagitan nito ay maa-access natin ang button sa Form1 (linya 5,7,9 at 15).
Namespace WindowsApplication1 ( public partial class Form2: Form ( private Button but1; // ang variable na ito ay maglalaman ng link papunta sa button button1 mula sa form Form1 public Form2(Button but) // kumuha ng link sa button sa variable but ( but1 = ngunit; // ngayon but1 ay magiging isang link sa button button1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1.Text = "test"; // palitan ang text sa button na button1 ng Form1 ) ) )
ika-3 paraan. Access sa buong form ng magulang.
Upang gawin ito, kailangan mong gumawa ng mga pagbabago sa ilang mga file, ngunit sa parehong oras ay magkakaroon kami ng access sa lahat ng mga elemento ng parent form at hindi na kailangang magpasa ng isang link sa bawat elemento, tulad ng sa pamamaraan 1.
Hakbang 1. Nasa file Program.cs lumikha ng pampublikong variable f1 (linya 5).
Namespace WindowsApplication1 ( static class Program ( public static Form1 f1; // variable na maglalaman ng link sa form na Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1() ) );)))
Hakbang 2. Pagbubukas Form1.Designer.cs at sa loob nito, para sa mga elemento na kailangang ma-access mula sa ibang form, nagbabago kami pribado sa pampubliko. Halimbawa, gawin nating available ang button1 sa Form1 para sa mga pagbabago.
Pampublikong System.Windows.Forms.Button button1; // pinalitan ng pribado ng pampubliko
Hakbang 3. Kapag gumagawa ng Form1, nagtatalaga kami ng variable f1 ng isang link sa form na ito (linya 7)
Namespace WindowsApplication1 ( public partial class Form1: Form ( public Form1() ( Program.f1 = this; // now f1 will be a link to the form Form1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = bagong Form2(); frm.ShowDialog(); ) ) )
Hakbang 4. Ngayon mula sa ganap na anumang anyo o mula sa anumang klase maaari mong ma-access ang button1 na elemento na matatagpuan sa Form1 tulad nito: Program.f1.button1. Halimbawa, hayaan ang button sa Form2 na baguhin ang button na text sa Form1:
Namespace WindowsApplication1 ( public partial class Form2: Form ( public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Program.f1.button1.Text = "test"; // Baguhin ang text sa pindutan ng form Form1 ) ) )
Ngayon gusto kong pag-usapan kung paano lumikha ng isang proyekto ng Windows Forms sa C++ sa Visual Studio 2013 IDE. Ang katotohanan ay, simula sa VS 2012, ang item ng Windows Forms Application ay inalis mula sa listahan ng mga proyekto na maaaring malikha. Ngayon ay pinag-uusapan ko ang tungkol sa isa sa C++; maaari kang lumikha ng ganoong proyekto sa C# sa pamamagitan ng pagpili ng naaangkop na item sa seksyon para sa mga nilikhang proyekto. Gayunpaman, ang katotohanan na ang naturang proyekto ay hindi mapipili mula sa listahan ay hindi nangangahulugan na hindi mo ito magagawa sa iyong sarili. Ito mismo ang gusto kong pag-usapan sa artikulong ito.
Ang unang bagay na kailangan mong gawin ay ilunsad ang Visual Studio. Kapag nailunsad ang VS, i-click ang File > New > Project
Pagkatapos nito, magbubukas ang isang window na humihiling sa iyong pumili ng uri ng proyekto. Kailangan nating piliin ang CLR subsection sa Visual C++ section at piliin ang Blank CLR Project.
Kapag nalikha ang proyekto, sa Solution Explorer, i-right-click ang ginawang proyekto. Sa menu ng konteksto na bubukas, piliin ang Magdagdag > Gumawa ng Elemento at sa magbubukas na menu, sa seksyong UI, piliin ang Mga Form ng Windows
Kapag naidagdag na ang form, piliin ang MyForm.cpp file sa Solution Explorer. Magbubukas sa harap mo ang isang bagong tab na may isang linya ng code:
#include "MyForm.h"
Kailangan naming idagdag ang sumusunod na code sa file na ito:
Paggamit ng namespace System; gamit ang namespace System::Windows::Forms; walang bisa Pangunahing(array
Pagkatapos nito sa mga katangian ng proyekto. Pumili ng subsection Sistema Linker ng seksyon at sa linya ng Subsystem mula sa drop-down na menu, piliin ang Windows (/SUBSYSTEM:WINDOWS) at i-click ang Ilapat.
Nang hindi isinasara ang window ng mga katangian ng proyekto, pumunta sa Advanced na subsection at sa linya Punto ng pagpasok nagsusulat kami Pangunahing at pagkatapos ay pindutin ang key OK.
Kinukumpleto nito ang mga setting ng proyekto. Upang i-edit ang hitsura ng form, kailangan mong pumunta sa MyForm.h [Designer] na tab sa pamamagitan ng pag-double click sa MyForm.h file sa Solution Explorer.
Sa kabila ng katotohanan na ang aking opinyon tungkol sa Visual Studio ng Microsoft ay pareho pa rin, kung minsan kailangan mong gumawa ng isang bagay dito. Kung maiintindihan natin ang katotohanang sumusulat tayo, sa katunayan, hindi sa C++, ngunit sa tinatawag na C++/CLI, ang pagtatrabaho sa mga pamilyar na visual na bahagi ay hindi magiging iba sa parehong mga kapaligiran ng Borland. Ngunit maaari itong lumikha ng mga problema, kumpara sa Builder. Isaalang-alang natin ang 3 tipikal na sitwasyon ng pagtatrabaho sa isang application na naglalaman ng higit sa isang form. Ang halimbawang kapaligiran ay libre Visual C++ 2010 Express, ipinapalagay na ang pangunahing form ay may default na pangalan na Form1.
Isang halimbawa ng pagbuo at pagtawag sa isang form gamit ang program
Maaaring isagawa ang code na ito, halimbawa, sa pamamagitan ng pag-click sa isang button sa pangunahing form na Form1.
Form^form2 = gcnew Form(); Button^ button2 = gcnew Button(); button2->Text = L"OK"; button2->Lokasyon = Point(10,10); form2->Text = L"Aking window"; form2->HelpButton = totoo; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; form2->Controls->Add(button2); form2->ShowDialog();
Upang magdagdag ng tagapangasiwa ng pag-click para sa button na nabuong programmatically2, isulat lang bago ang huling linya ng code:
Button2->Click += gcnew System::EventHandler(ito, &Form1::button2_Click);
Bago tawagan ang form2->ShowDialog() o form2->Show() na paraan;
Sa kasong ito, ang handler code ay matatagpuan sa kasalukuyang module na Form1.h:
Pribado: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) ( MessageBox::Show("Here"); )
Tumawag sa isa pang form mula sa pangunahing form
Sa menu, piliin ang Project - Magdagdag ng bagong elemento - Form - pangalan Form2
Magdagdag tayo ng operator
#include "Form2.h"
bago ang unang namespace sa Form1.h (iyon ay, sa pinakadulo simula ng file).
Isama natin ang isang pointer sa instance ng klase sa pampublikong seksyon ng klase ng Form1:
Form2^F2;
Idagdag natin ang code kung saan kailangan nating gumawa at tawagan ang pangalawang form:
F2=gcnewForm2(); F2->Ipakita();
Upang ma-program na tanggalin ang pangalawang form, ang sumusunod na code ay angkop:
Tanggalin ang F2;
Dapat tandaan na ang pointer ay nag-iimbak ng address ng isang form lamang, ang isa na huling ginawa. Kung sunud-sunod tayong gagawa ng ilang form gamit ang code na ito, ang huli lang ang tatanggalin. Bilang kahalili, subukan ang hanay ng hugis na inilarawan sa ibaba.
Ilarawan natin ang kinakailangang data sa klase ng form ng Form1 (dito ang pangalan at namespace ng proyekto ng Tabulator, kung kinakailangan, palitan ng sarili mo):
Static const int MAX_FORMS = 100; //Maximum na bilang ng mga form int FormCount; //Bumuo ng counter array
Pagkatapos ay sinisimulan namin ang data gamit ang kaganapan sa Pag-load ng pangunahing form:
FormCount=0; F2 = gcnew array
Pagkatapos ay ipapatupad namin ang code upang lumikha ng susunod na form
Kung(FormCount
at ang pagtanggal nito:
Kung (FormCount) ( tanggalin ang F2; FormCount--; )
Kung nais nating lumikha ng mga form ng bata nang hindi hiwalay, ngunit sa loob ng form ng magulang, pagkatapos ay sa mga katangian ng Form1 kailangan nating ipahiwatig na ito ay isang "ninuno" (itakda ang IsMdiParent property = true), at bago ipakita ang form ng bata gamit ang F2->Show() operator, markahan ito bilang isang bata Form1:
F2->MdiParent = ito;
Tumawag ng paraan ng form ng magulang mula sa form ng bata
Halos hindi namin magagawa nang hindi gumagamit ng mga .cpp na file, na hindi masama - ang pagsulat ng code sa mga .h na file ay karaniwang sinisira ang tamang C system :)
Ilarawan natin ang proseso nang hakbang-hakbang.
1) Mayroong 2 form - Form1 at Form2, sa Form1 ay mayroong Button (button1, magbubukas sa pangalawang form) at Label (label1, dito natin babaguhin ang text). Sa Form2 - button1, kapag na-click, magbabago ang text sa label1.
2) Dahil kailangan nating magkaroon ng access mula sa unang anyo hanggang sa pangalawa, at mula sa pangalawa hanggang sa una, ang problema ng mga cross-reference ay lilitaw (kapag ang Form1.h ay tumutukoy sa Form2.h, na, naman, ay muling tumutukoy sa Form1.h). Upang maiwasan ito, ililipat namin ang code ng unang form (Form1), na magkakaroon ng access sa pangalawang form (Form2), mula sa .h file patungo sa .cpp file. Kaya, kailangan mong lumikha ng isang file na Form1.cpp.
3) Magdeklara ng pampublikong Set method sa Form1.h para mapalitan mo ang text ng label1 (maaaring isulat ang code sa dulo ng file, pagkatapos ng #pragma endregion):
Pampubliko: void Set(String^ text) ( label1->Text = text; )
4) Sa Form2.h file isinama namin ang Form1.h (sa simula):
#include "Form1.h"
at lumikha ng isang constructor na tatanggap at magse-save ng isang link sa unang form para sa karagdagang paggamit:
Form2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //maaari kang sumulat ng link kaagad sa ibaba: pribado: Form1^ parentForm;
5) Sa pag-click sa button sa Form2, tatawagin namin ang Set method ng parent form:
Pribado: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) ( parentForm->Set("hello from form2"); parentForm->Show(); this->Hide(); )
6) Ito ay nananatiling buksan ang pangalawang anyo sa unang anyo. Upang gawin ito, inililipat namin ang handler ng pag-click ng button mula sa Form1.h patungo sa Form1.cpp , at sa .h file ay iniiwan lamang namin ang deklarasyon nito.
Ang tanong na tinutugunan sa artikulong ito ay mas malamang na nauugnay sa paksa ng pagbuo ng isang arkitektura ng application, at hindi partikular sa problemang isinasaalang-alang. Ang paglilipat ng data mula sa isang form patungo sa isa pa ay hindi mahirap sa lahat. Upang gawin ito, sapat na upang gawing bukas ang kontrol kung saan ang data na gusto nating makuha, iyon ay, markahan ito ng pampublikong modifier. Gayundin, posible ang isa pang pagpipilian. Halimbawa, sa unang anyo lumikha kami ng isang bagay ng pangalawang anyo sa pamamagitan ng pagpasa ng isang sanggunian sa ating sarili sa tagabuo, iyon ay, sa pamamagitan ng pagpasa ng isang sanggunian sa una mula sa unang anyo hanggang sa pangalawa
SecondForm secondForm = bagong SecondForm(ito);
Naturally, bago gawin ito, dapat mong alagaan ang paglikha ng labis na karga para sa tagabuo ng pangalawang form.
At ang pamamaraang ito ay medyo karaniwan. Gayunpaman, sa pagiging simple nito, nagdadala ito ng maraming potensyal na problema, ang pangunahing isa ay isang paglabag sa prinsipyo ng encapsulation. Sa isang salita, ang pangalawang anyo ay hindi dapat malaman ang anumang bagay tungkol sa pagkakaroon ng una at, higit pa, hindi ito dapat maimpluwensyahan.
Ang solusyon sa problemang ito ay medyo simple. Direktang tingnan natin ang code. Sa taga-disenyo, lumikha kami ng pangunahing form (ito ay ilulunsad kapag nagsimula ang application). Maglagay tayo ng isa TextBox, Label At Pindutan.
Sa pamamagitan ng pag-click sa button, magbubukas ang pangalawang form at ang text mula sa text field ng pangunahing form ay ililipat sa text field ng pangalawang form. Sa una, ang pangalawang anyo ay ganito ang hitsura:
Katulad ng una, mayroon itong parehong mga kontrol. Hindi na natin kailangan. Inilunsad ng entry point ng application ang pangunahing form:
Paggamit ng System; gamit ang System.Collections.Generic; gamit ang System.Linq; gamit ang System.Windows.Forms; namespace From1FormTo2 ( static class Program ( // Ang pangunahing entry point para sa application. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )
Ang pangunahing form code ay ganito ang hitsura:
Paggamit ng System; gamit ang System.Collections.Generic; gamit ang System.ComponentModel; gamit ang System.Data; gamit ang System.Drawing; gamit ang System.Linq; gamit ang System.Text; gamit ang System.Windows.Forms; namespace From1FormTo2 ( public partial class MainForm: Form ( //second form SecondForm secondForm; //constructor public MainForm() ( InitializeComponent(); ) //data transfer event handler //mula sa pangunahing form hanggang sa pangalawang private void btn_mainForm_Click(object nagpadala, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData(); ) ) )
Alinsunod dito, huwag kalimutang ikonekta ang pindutan sa kaganapan I-click. Dito sa pangunahing form na klase mayroong isang patlang SecondForm secondForm, na kumakatawan sa pangalawang anyo na bagay. Kapag nag-click ka sa pindutang "Isumite", ang pangalawang form ay nilikha (tinatawag ang overloaded na tagabuo, gagawin namin ito sa ibang pagkakataon) at inilunsad gamit ang pamamaraan ShowDialog(). Sa kasong ito, ang pamamaraang ito ay angkop para sa amin. Bukod dito, pagkatapos nito tinitiyak naming suriin kung ang pangalawang form ay sarado, ngunit nag-click sa pindutan nito. Kung na-click ang isang button sa pangalawang form, dapat tanggapin ng unang form ang data mula sa pangalawa. Nangyayari ito sa pamamagitan ng pagtawag sa pamamaraan ReturnData() sa pangalawang anyo.
Ngayon ang pinaka-kagiliw-giliw na bahagi ay ang code ng pangalawang form:
Paggamit ng System; gamit ang System.Collections.Generic; gamit ang System.ComponentModel; gamit ang System.Data; gamit ang System.Drawing; gamit ang System.Linq; gamit ang System.Text; gamit ang System.Windows.Forms; namespace From1FormTo2 ( public partial class SecondForm: Form ( // overloaded constructor public SecondForm(string data) ( InitializeComponent(); tb_secondForm.Text = data; ) //data transfer event handler //mula sa pangalawang form hanggang sa pangunahing private void btn_secondForm_Click (object sender, EventArgs e) ( this.DialogResult = DialogResult.OK; ) //pampublikong paraan para ma-access //ang text field ng form na ito public string ReturnData() ( return (tb_secondForm.Text.Trim()); ) ) )
Tulad ng nakikita mo, mayroong isang solong constructor overload na tumatanggap ng isang uri ng string. Tandaan na sinusubukan naming maglipat ng text mula sa isang TextBox. Sa constructor, ang mga bahagi ay naka-iskedyul na masimulan at ang teksto ng field ng teksto ay nakatakda sa ipinadalang halaga mula sa unang anyo. Susunod, sa pamamagitan ng pag-subscribe sa kaganapan I-click para sa button ng pangalawang form, gumawa kami ng handler btn_secondForm_Click, na ginagaya ang pagpapatakbo ng "Ok" na button ng anumang dialog box. Kaya, sa pamamagitan ng pag-click sa pindutang "Isumite" (sa pangalawang form), isinasagawa namin ang kundisyon
(secondForm .DialogResult == DialogResult .OK)
Ang unang anyo, samakatuwid, ang pagtawag sa pamamaraan secondForm.ReturnData(), itinakda namin ang field ng text ng unang form sa halaga ng field ng text ng pangalawang form.
Ang pagpapatakbo ng pamamaraang ito, sa palagay ko, ay hindi na nangangailangan ng paliwanag. Ibinabalik lang nito ang text mula sa isang field ng text, habang pinapanatili itong pribado.
Bilang resulta, inilipat namin ang data sa pangalawang anyo mula sa una at mula sa pangalawa hanggang sa una nang hindi lumalabag sa mga prinsipyo ng encapsulation.
Subukang ilagay ang text na "aaa" sa text field ng unang form at i-click ang button. Makikita mo ang text na ito sa field ng text sa pangalawang form na bubukas. Subukang palitan ang text sa “aaa ppp” at i-click ang button. Makikita mo kung paano, pagkatapos isara ang pangalawang form, ang tekstong ito ay lilitaw sa field ng teksto ng pangunahing form.
Ngayon, sa tingin ko ay mas makakapaglipat ka ng data sa pagitan ng mga form. Sa susunod na artikulo ay pag-uusapan natin kung paano ito gagawin sa mga aplikasyon ng ASP.NET.