Kako odpreti drugega iz enega obrazca. Dodajanje obrazcev. Interakcija med oblikami. Primer konstruiranja in programskega klica obrazca

Vprašanje, obravnavano v tem članku, se bolj verjetno nanaša na temo izgradnje arhitekture aplikacije in ne posebej na obravnavani problem. Prenos podatkov iz enega obrazca v drugega sploh ni težak. Za to je dovolj, da kontrolnik, katerega podatke želimo pridobiti, odpremo, to pomeni, da ga označimo z modifikatorjem public. Možna je tudi druga možnost. Na primer, v prvi obliki ustvarimo objekt druge oblike tako, da konstruktorju posredujemo referenco nase, to je tako, da prenesemo referenco na prvo iz prve oblike v drugo
SecondForm secondForm = new SecondForm(this);
Seveda, preden to storite, morate poskrbeti za ustvarjanje preobremenitve za konstruktorja druge oblike.

In ta metoda je precej pogosta. Vendar pa s svojo preprostostjo nosi veliko potencialnih težav, med katerimi je glavna kršitev načela enkapsulacije. Z eno besedo, druga oblika ne bi smela vedeti ničesar o obstoju prve in še več, ne bi smela vplivati ​​nanjo.

Rešitev tega problema je precej preprosta. Poglejmo neposredno kodo. Ustvarjamo v dizajnerju glavna oblika(zagnal se bo ob zagonu aplikacije). Dajmo enega TextBox, Oznaka in Gumb.

S klikom na gumb se odpre drugi obrazec in besedilo iz besedilno polje glavni obrazec bo prenesen v besedilno polje drugega obrazca. Na začetku je druga oblika videti takole:

Podobno kot prvi ima enake kontrole. Ne potrebujemo več. Vstopna točka aplikacije zažene glavni obrazec:

Uporaba sistema; z uporabo System.Collections.Generic; z uporabo System.Linq; z uporabo System.Windows.Forms; imenski prostor From1FormTo2 ( statični razred Program ( // Glavna vstopna točka za aplikacijo. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

Glavna koda obrazca izgleda takole:

Uporaba sistema; z uporabo System.Collections.Generic; using System.ComponentModel; z uporabo System.Data; z uporabo System.Drawing; z uporabo System.Linq; z uporabo System.Text; z uporabo System.Windows.Forms; imenski prostor From1FormTo2 ( javni delni razred MainForm: Form ( //drugi obrazec SecondForm secondForm; //konstruktor public MainForm() ( InitializeComponent(); ) //obravnavalec dogodka prenosa podatkov //od glavnega obrazca do drugega zasebnega void btn_mainForm_Click(object pošiljatelj, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData(); ) ) )

V skladu s tem ne pozabite gumba povezati z dogodkom Kliknite. Tukaj v razredu glavnega obrazca je polje SecondForm secondForm, ki predstavlja objekt druge oblike. Ko kliknete na gumb »Pošlji«, se ustvari drugi obrazec (pokliče se preobremenjeni konstruktor, ustvarili ga bomo kasneje) in se zažene z metodo Prikažipogovorno okno(). V tem primeru je ta metoda primerna za nas. Poleg tega po tem preverimo, ali je bil drugi obrazec zaprt, vendar smo kliknili na njegov gumb. Če ste kliknili gumb na drugem obrazcu, mora prvi obrazec sprejeti podatke iz drugega. To se zgodi s klicem metode VrniPodatke() v drugi obliki.

Najbolj zanimiv del je koda druge oblike:

Uporaba sistema; z uporabo System.Collections.Generic; using System.ComponentModel; z uporabo System.Data; z uporabo System.Drawing; z uporabo System.Linq; z uporabo System.Text; z uporabo System.Windows.Forms; imenski prostor From1FormTo2 ( javni delni razred SecondForm: Form ( //preobremenjen konstruktor public SecondForm(string data) ( InitializeComponent(); tb_secondForm.Text = data; ) //obravnavalec dogodkov prenosa podatkov //iz drugega obrazca v glavni zasebni void btn_secondForm_Click (pošiljatelj objekta, EventArgs e) ( this.DialogResult = DialogResult.OK; ) // javna metoda za dostop // besedilno polje tega obrazca javni niz ReturnData() ( return (tb_secondForm.Text.Trim()); ) ) )

Kot lahko vidite, obstaja ena preobremenitev konstruktorja, ki sprejme vrsto niza. Ne pozabite, da poskušamo prenesti besedilo iz polja TextBox. V konstruktorju so komponente načrtovane za inicializacijo in besedilo besedilnega polja je nastavljeno na preneseno vrednost iz prvega obrazca. Nato pa s prijavo na dogodek Kliknite za gumb druge oblike smo ustvarili upravljalnik btn_secondForm_Click, ki simulira delovanje gumba »V redu« v katerem koli pogovornem oknu. Tako s klikom na gumb “Oddaj” (drugega obrazca) izvršimo pogoj

(secondForm .DialogResult == DialogResult .OK)

Prva oblika torej kliče metodo secondForm.ReturnData(), besedilno polje prvega obrazca nastavimo na vrednost besedilnega polja drugega obrazca.

delo ta metoda, mislim, da ne potrebuje več razlage. Preprosto vrne besedilo iz enega polja z besedilom, pri čemer ostane zasebno.

Posledično smo podatke v drugo obliko prenesli iz prve in iz druge v prvo, ne da bi pri tem kršili načela enkapsulacije.

Poskusite vnesti besedilo "aaa" v besedilno polje prvega obrazca in kliknite gumb. To besedilo boste videli v besedilnem polju v drugem obrazcu, ki se odpre. Poskusite spremeniti besedilo v "aaa ppp" in kliknite gumb. Videli boste, kako se bo po zaprtju drugega obrazca to besedilo prikazalo v besedilnem polju glavnega obrazca.

Zdaj mislim, da boste lahko pravilneje prenašali podatke med obrazci. V naslednjem članku bomo govorili o tem, kako to storiti v aplikacijah ASP.NET.

Zadnja posodobitev: 31. 10. 2015

Če želite projektu dodati še en obrazec, z desno miškino tipko kliknite ime projekta v oknu Raziskovalca rešitev in izberite Dodaj->Obrazec Windows...

Dajmo novemu obrazcu neko ime, npr. Form2.cs:

Tako smo našemu projektu dodali drugo obliko. Zdaj pa poskusimo implementirati interakcijo med dvema oblikama. Recimo, da bo prvi obrazec poklical drugi obrazec, ko kliknete gumb. Najprej dodamo gumb v prvi obrazec, Form1, in dvokliknemo na gumb, da gremo na kodno datoteko. Preusmerjeni bomo do urejevalnika dogodkov klika gumba, ki je privzeto ustvarjen po dvokliku gumba:

Zasebni prazen gumb1_Klik (pošiljatelj predmeta, EventArgs e) ( )

Zdaj mu dodajmo kodo za klic drugega obrazca. Naš drugi obrazec se imenuje Form2, zato najprej ustvarimo predmet tega razreda, nato pa za prikaz na zaslonu pokličemo metodo Show:

Zasebni void button1_Click(object sender, EventArgs e) ( Form2 newForm = new Form2(); newForm.Show(); )

Zdaj pa naredimo obratno – tako da druga oblika vpliva na prvo. Medtem ko druga oblika ne ve za obstoj prve. Če želite to popraviti, morate nekako prenesti informacije o prvem obrazcu v drugi obrazec. Za to bomo uporabili posredovanje povezave do obrazca v konstruktorju.

Torej pojdimo na drugi obrazec in pojdimo na njegovo kodo - z desno tipko miške kliknite na obrazec in izberite Ogled kode. Zaenkrat je prazen in vsebuje samo konstruktor. Ker C# podpira preobremenitev metod, lahko ustvarimo več metod in konstruktorjev z različnimi parametri in pokličemo enega od njih, odvisno od situacije. Torej, spremenimo kodno datoteko drugega obrazca v naslednje:

Uporaba sistema; z uporabo System.Collections.Generic; using System.ComponentModel; z uporabo System.Data; z uporabo System.Drawing; z uporabo System.Linq; z uporabo System.Text; z uporabo System.Threading.Tasks; z uporabo System.Windows.Forms; imenski prostor HelloApp ( javni delni razred Form2: Obrazec ( javni Form2() ( InitializeComponent(); ) javni Form2(Form1 f) ( InitializeComponent(); f.BackColor = Color.Yellow; ) ) )

Pravzaprav smo dodali tukaj nov konstruktor public Form2(Form1 f), v katerem dobimo prvi obrazec in mu nastavimo rumeno ozadje. Zdaj pa preidimo na kodo prvega obrazca, kjer smo poklicali drugi obrazec in ga spremenili v naslednje:

Zasebni void button1_Click(object sender, EventArgs e) ( Form2 newForm = new Form2(this); newForm.Show(); )

Ker v tem primeru ključna beseda this predstavlja referenco na trenutni objekt - objekt Form1, ga bo ob ustvarjanju drugega obrazca prejel (povezavo) in preko njega nadzoroval prvi obrazec.

Po kliku na gumb bo ustvarjen drugi obrazec, ki bo takoj spremenil barvo prvega obrazca.

Ustvarimo lahko tudi objekte trenutne oblike:

Zasebni void button1_Click(object sender, EventArgs e) ( Form1 newForm1 = new Form1(); newForm1.Show(); Form2 newForm2 = new Form2(newForm1); newForm2.Show(); )

Pri delu z več obrazci morate upoštevati, da je eden od njih glavni - ki se najprej zažene v datoteki Program.cs. Če imamo odprtih več obrazcev hkrati, potem ko zapremo glavnega, se zapre celotna aplikacija in z njo tudi vsi ostali obrazci.

Kljub temu, da je moje mnenje o Microsoftovem Visual Studiu še vedno enako, je včasih treba na njem kaj narediti. Če se sprijaznimo z dejstvom, da pravzaprav ne pišemo v C++, temveč v tako imenovanem C++/CLI, se delo z znanimi vizualnimi komponentami ne bo tako razlikovalo od istih okolij Borland. Lahko pa povzroči težave v primerjavi z Builderjem. Razmislimo o 3 tipičnih situacijah dela z aplikacijo, ki vsebuje več kot en obrazec. Primer okolja je brezplačen Visual C++ 2010 Express, predpostavlja se, da ima glavni obrazec privzeto ime Form1.

Primer konstruiranja in programskega klica obrazca

To kodo je mogoče izvesti na primer s klikom na gumb v glavnem obrazcu Form1.

Form^form2 = gcnew Form(); Button^ button2 = gcnew Button(); gumb2->Besedilo = L"OK"; gumb2->Lokacija = Točka(10,10); form2->Besedilo = L"Moje okno"; form2->HelpButton = true; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; obrazec2->Kontrolniki->Dodaj(gumb2); obrazec2->Pokažipogovorno okno();

Če želite dodati obravnavo klikov za programsko ustvarjen gumb button2, napišite pred zadnjo vrstico kode:

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

Preden se pokliče metoda form2->ShowDialog() ali form2->Show();

V tem primeru se koda za obravnavo nahaja v trenutnem modulu Form1.h:

Zasebno: System::Void button2_Click(System::Object^ pošiljatelj, System::EventArgs^ e) ( MessageBox::Show("Tukaj"); )

Pokličite drug obrazec iz glavnega obrazca

V meniju izberite Projekt - Dodaj nov element- Obrazec - ime Obrazec2

Dodajmo operaterja

#include "Form2.h"

pred prvim imenskim prostorom v Form1.h (to je na samem začetku datoteke).

V javni del razreda Form1 vključimo kazalec na primerek razreda:

obrazec2^F2;

Dodajmo kodo, kjer moramo ustvariti in poklicati drugi obrazec:

F2=gcnewForm2(); F2->Pokaži();

Za programsko brisanje drugega obrazca je primerna naslednja koda:

Izbriši F2;

Upoštevati je treba, da kazalec shrani naslov samo enega obrazca, tistega, ki je bil ustvarjen zadnji. Če s to kodo zaporedoma ustvarimo več obrazcev, bo izbrisan samo zadnji. Druga možnost je, da preizkusite niz oblik, ki je opisan spodaj.

Opišimo potrebne podatke v razredu obrazca Form1 (tu ime in imenski prostor projekta Tabulator po potrebi zamenjajte s svojim):

Statična const int MAX_FORMS = 100; //Največje število obrazcev int FormCount; //Oblikuje matriko števcev ^F2; //Kazalec na niz obrazcev

Nato inicializiramo podatke z dogodkom Load glavnega obrazca:

FormCount=0; F2 = gcnova matrika (MAX_FORMS);

Nato bomo implementirali kodo za ustvarjanje naslednjega obrazca

If(FormCount Prikaži(); ) else MessageBox::Show("Preveč obrazcev!");

in njegovo odstranitev:

Če (FormCount) ( izbriši F2; FormCount--; )

Če ne želimo ustvariti podrejenih obrazcev ločeno, ampak znotraj nadrejenega obrazca, potem moramo v lastnostih obrazca Form1 navesti, da je "prednik" (nastavite lastnost IsMdiParent = true), in preden prikažete podrejeni obrazec z uporabo F2->Show() operator, označite ga kot podrejenega obrazca Form1:

F2->MdiParent = to;

Pokličite metodo nadrejenega obrazca iz podrejenega obrazca

Skoraj ne moremo brez uporabe datotek .cpp, kar ni slabo - pisanje kode v datoteke .h praviloma pokvari pravilen sistem C :)

Opišemo postopek korak za korakom.

1) Obstajata 2 obrazca - obrazec1 in obrazec2, na obrazcu1 je gumb (gumb1, bo odprl drugi obrazec) in oznaka (label1, tukaj bomo spremenili besedilo). Na Form2 - gumb1, ko kliknete, se besedilo v label1 spremeni.

2) Ker moramo imeti dostop od prvega obrazca do drugega in od drugega do prvega, se bo pojavil problem navzkrižnih sklicevanj (ko se Form1.h nanaša na Form2.h, ta pa se spet sklicuje na obrazec1.h). Da bi se temu izognili, bomo kodo prve forme (Form1), ki bo imela dostop do druge forme (Form2), premaknili iz datoteke .h v datoteko .cpp. Zato morate ustvariti datoteko Form1.cpp.

3) V Form1.h deklarirajte javno metodo Set, tako da lahko spremenite besedilo label1 (kodo lahko napišete na koncu datoteke, za #pragma endregion):

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

4) V datoteko Form2.h vključimo Form1.h (na začetku):

#include "Form1.h"

in ustvarite konstruktor, ki bo sprejel in shranil povezavo do prvega obrazca za nadaljnjo uporabo:

Form2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //takoj spodaj lahko napišete povezavo: zasebno: Form1^ parentForm;

5) Ko kliknemo gumb v Form2, bomo poklicali metodo Set nadrejenega obrazca:

Zasebno: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) ( parentForm->Set("hello from form2"); parentForm->Show(); this->Hide(); )

6) Ostaja še odpiranje drugega obrazca v prvem obrazcu. Da bi to naredili, premaknemo obdelovalnik klikov gumba iz Form1.h v Form1.cpp in v datoteki .h pustimo samo njegovo deklaracijo.

Včasih je treba med izvajanjem programa dostopati do elementov ene oblike iz druge. Na primer, obstaja obrazec Form1, iz njega odpremo drug obrazec Form2 in zdaj, ko delamo v obrazcu Form2, moramo dostopati do elementov nadrejenega obrazca Form1. Našel sem več načinov za to.

1. metoda. Posredovanje sklica na javno spremenljivko.

Imenski prostor WindowsApplication1 ( javni delni razred Form1: Obrazec ( javni Form1() ( InitializeComponent(); ) zasebni void button1_Click(objekt pošiljatelj, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // pošlji povezava do gumba v obliki Form2 frm.ShowDialog(); ) ) )

V obrazcu Form2 bo spremenljivka, do katere je bila posredovana povezava, zdaj ustrezala button1 iz obrazca Form1

Imenski prostor WindowsApplication1 ( javni delni razred Form2: Form ( javni gumb but1; // ta spremenljivka bo vsebovala povezavo do gumba1 iz obrazca Form1 public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1. Besedilo = "test"; // spremenite besedilo na gumbu button1 obrazca1 ) ) )

2. metoda. Posredovanje povezave do podrejenega obrazca.

Pri prvi metodi je bistvo približno enako. Ko odpremo Form2, vanj posredujemo povezavo do elementa, ki ga nameravamo kasneje spremeniti.

Imenski prostor WindowsApplication1 ( javni delni razred Form1: Obrazec ( javni Form1() ( InitializeComponent(); ) zasebni void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(this.button1); // posredovanje povezave do gumba v obrazec Form2 frm.ShowDialog(); ) ) )

Sedaj moramo v Form2 ustvariti spremenljivko, ki bo vsebovala povezavo do tega gumba in preko nje bomo dostopali do gumba na Form1 (vrstice 5,7,9 in 15).

Imenski prostor WindowsApplication1 ( javni delni razred Form2: Form ( private Button but1; // ta spremenljivka bo vsebovala povezavo do gumba button1 iz obrazca Form1 public Form2(Button but) // pridobite povezavo do gumba v spremenljivki but ( but1 = but; // zdaj bo but1 povezava do gumba button1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1.Text = "test"; // spremeni besedilo na gumbu button1 obrazca1 ) ) )

3. metoda. Dostop do celotnega nadrejenega obrazca.

Če želite to narediti, morate narediti spremembe v več datotekah, hkrati pa bomo imeli dostop do vseh elementov nadrejenega obrazca in vam ni treba posredovati povezave do vsakega elementa, kot pri metodi 1.

Korak 1. V datoteki Program.cs ustvarite javno spremenljivko f1 (vrstica 5).

Imenski prostor WindowsApplication1 ( statični razred Program ( public static Form1 f1; // spremenljivka, ki bo vsebovala povezavo do obrazca Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1( ) ); ) ) )

2. korak Otvoritev Form1.Designer.cs in v njem za elemente, do katerih bo treba dostopati iz druge forme, spremenimo zasebno na javnosti. Na primer, naredimo button1 na Form1 na voljo za spremembe.

Javni System.Windows.Forms.Button button1; // zasebno zamenjano z javnim

3. korak. Ko ustvarjamo Form1, spremenljivki f1 dodelimo povezavo do tega obrazca (vrstica 7)

Imenski prostor WindowsApplication1 ( javni delni razred Form1: Obrazec ( javni Form1() ( Program.f1 = this; // zdaj bo f1 povezava do obrazca Form1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = nov obrazec2(); frm.ShowDialog(); ) ) )

4. korak Zdaj lahko iz absolutno katerega koli obrazca ali iz katerega koli razreda dostopate do elementa button1, ki se nahaja na obrazcu Form1, takole: Program.f1.button1. Na primer, naj gumb na Form2 spremeni besedilo gumba na Form1:

Imenski prostor WindowsApplication1 ( javni delni razred Form2: Obrazec ( javni Form2() ( InitializeComponent(); ) zasebni void button1_Click(object sender, EventArgs e) ( Program.f1.button1.Text = "test"; // Spremenite besedilo na gumb obrazca Obrazec1 ) ) )

Avtor: admin.

Učenje C# je počasno. vendar se zvesto nadaljuje. Ravno pred kratkim sem
dal primer, kako odpreti drugega iz enega obrazca v Visual C#. Načeloma je vse preprosto.

Danes se je pojavila naslednja naloga: zaženite modalni obrazec iz glavnega obrazca aplikacije; ko je zaprt, mora ta obrazec posredovati nekaj podatkov (besedilo, vrednosti lastnosti itd.) kontrolnikom na glavnem obrazcu. Tega problema ni mogoče rešiti z metodo, opisano v prejšnji objavi o obrazcih, ker v tem primeru preprosto ustvarimo nov obrazec z novimi vrednostmi za vse lastnosti. Na srečo ima C# čudovit zbiralnik smeti ... Toda bistvo ni zbiralnik, ampak kako odpreti podrejeni obrazec v C# in se nato iz njega vrniti v glavni obrazec?

Za začetek nastavimo začetne (začetne) podatke.

torej. Imamo glavno prijavnico:

Ta obrazec vsebuje tudi TextBox z imenom TBDialog in gumb Button, na katerega moramo klikniti:

  1. Pass value Lastnosti besedila iz TBDialog v TBMain;
  2. Zapri fDialog;

Zdaj pa si poglejmo celoten postopek po vrsti.

Najprej si velja zapomniti, da je privzeto vsem lastnostim, spremenljivkam in metodam v C# dodeljen modifikator zasebno– torej, da bi prišli od druge forme do kontrole na prvi, moramo nastaviti modifikator za TBMain javnosti na svojem. Če želite to narediti, izberite element TBMain v oblikovalcu obrazca, pojdite v okno lastnosti in spremenite vrednost nepremičnine Modifikatorji z zasebno na javnosti

Zdaj bo TBMain viden v drugih objektih. Gremo naprej. Če želimo odpreti obrazec v modalnem načinu, moramo uporabiti eno od dveh možnosti za metodo ShowDialog():

public DialogResult ShowDialog() ; public DialogResult ShowDialog(IWin32Window lastnik) ;

V prvem primeru metoda prikaže obrazec kot modalno pogovorno okno s trenutno aktivnim oknom, nastavljenim kot lastnik, v drugem primeru pa lahko samostojno določimo, kateri obrazec bo postal lastnik za naše modalno okno.

Na primer, uporabimo drugo različico metode ShowDialog() in prikažimo drugi obrazec modalno. Da bi to naredili, bomo napisali naslednje:

Tukaj sem spet izkoristil ključna beseda to , ki kaže na trenutni objekt, tj. nastavite glavni obrazec kot lastnika ( fMain). Zdaj pa preidimo neposredno na rešitev našega problema in odgovorimo na vprašanje: kako prenesti vrednost iz ene oblike v drugo? Vsaka kontrola ima izjemno lastnost Lastnik – ki kaže na starša:

Zdaj lahko zaženete projekt in se prepričate, da se besedilo iz TextBoxa na podrejenem obrazcu popolnoma prenese v TextBox na prvem. Za vsak slučaj objavljam izvorno kodo projekta, obravnavanega v primeru.