Mõnikord on programmi täitmise ajal vaja pääseda juurde ühe vormi elementidele teisest. Näiteks on olemas vorm Vorm1, sellest avame teise Vorm2 ja nüüd, töötades vormis 2, peame ligi pääsema algvormi Vorm1 elementidele. Leidsin selleks mitu võimalust.

1. meetod. Viite edastamine avalikule muutujale.

Nimeruum WindowsApplication1 ( avalik osaline klass Vorm1: Vorm ( public Form1() ( InitializeComponent(); ) private void button1_Click(objekti saatja, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // saada link nupule kujul Form2 frm.ShowDialog(); ) ) )

Vormis 2 vastab muutuja, millele link edastati, nüüd vormi 1 nupule 1

Nimeruum WindowsApplication1 ( public partial class Form2: Form ( public Button but1; // see muutuja sisaldab linki nupule 1 vormi 1-st public Form2() ( InitializeComponent(); ) private void button1_Click(objekti saatja, EventArgs e) ( but1. Text = "test"; // muutke vormi1 nupu nupu1 teksti ) ) )

2. meetod. Linki edastamine alamvormile.

Põhiolemus on 1. meetodi puhul ligikaudu sama. Vorm2 avamisel edastame sellesse lingi elemendile, mida plaanime hiljem muuta.

Nimeruum WindowsApplication1 ( avalik osaline klass Vorm1: Vorm ( public Form1() ( InitializeComponent(); ) private void button1_Click(objekti saatja, EventArgs e) ( Form2 frm = new Form2(this.button1); // edastage link nupule vormile Form2 frm.ShowDialog(); ) ) )

Nüüd peame vormis 2 looma muutuja, mis sisaldab linki sellele nupule ja selle kaudu pääseme juurde vormi 1 nupule (read 5, 7, 9 ja 15).

Nimeruum WindowsApplication1 ( avalik osaline klass Vorm2: Vorm ( privaatne nupp but1; // see muutuja sisaldab linki nupule nupule1 vormilt Form1 public Form2(Button but) // hankib lingi muutujas aga ( but1 = but; // nüüd on but1 link nupule button1 InitializeComponent(); ) privaatne void nupp1_Click(objekti saatja, EventArgs e) ( but1.Text = "test"; // muuda vormi1 nupul 1 olevat teksti ) ) )

3. meetod. Juurdepääs kogu vanemvormile.

Selleks peate tegema muudatusi mitmes failis, kuid samal ajal on meil juurdepääs põhivormi kõikidele elementidele ja me ei pea igale elemendile linki edastama, nagu meetodi 1 puhul.

Samm 1. Failis Programm.cs luua avalik muutuja f1 (rida 5).

Nimeruum WindowsApplication1 ( staatiline klass Program ( avalik staatiline vorm1 f1; // muutuja, mis sisaldab linki vormile Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1() ) ) ) )

2. samm. Avamine Vorm1.Designer.cs ja selles muudeme elementide puhul, millele tuleb juurde pääseda muult vormilt privaatne peal avalik. Näiteks teeme vormil 1 nupu 1 muudatuste jaoks kättesaadavaks.

Public System.Windows.Forms.Button button1; // asendati privaatne avalikuga

3. samm. Vormi1 loomisel omistame muutujale f1 sellele vormile lingi (rida 7)

Nimeruum WindowsApplication1 ( avalik osaline klass Vorm1: vorm ( avalik vorm1() ( Program.f1 = see; // nüüd on f1 link vormile Form1 InitializeComponent(); ) privaatne void nupp1_Click(objekti saatja, EventArgs e) ( Vorm2 frm = uus vorm2(); frm.ShowDialog(); ) ) )

4. samm. Nüüd pääsete absoluutselt igast vormist või igast klassist juurde vormil 1 asuvale elemendile button1 järgmiselt: Program.f1.button1. Näiteks laske vormil 2 oleval nupul vormil 1 olevat nupu teksti muuta:

Nimeruum WindowsApplication1 ( public partial class Form2: Form ( public Form2() ( InitializeComponent(); ) private void button1_Click(objekti saatja, EventArgs e) ( Program.f1.button1.Text = "test"; // Muutke teksti vormi nupp Vorm1)))

Selles artiklis käsitletav küsimus on tõenäolisemalt seotud rakenduse arhitektuuri loomise teemaga, mitte konkreetselt vaadeldava probleemiga. Andmete ülekandmine ühelt vormilt teisele pole sugugi keeruline. Selleks piisab, kui teha avatuks juhtelement, mille andmeid soovime hankida, ehk märkida see avaliku modifikaatoriga. Võimalik on ka teine ​​variant. Näiteks esimesel kujul loome teise vormi objekti, edastades konstruktorile viite iseendale, st edastades viite esimesele esimeselt vormilt teisele.
SecondForm secondForm = new SecondForm(this);
Loomulikult peaksite enne selle tegemist hoolitsema teise vormi konstruktori ülekoormuse tekitamise eest.

Ja see meetod on üsna levinud. Kuid oma lihtsuse tõttu kannab see palju võimalikke probleeme, millest peamine on kapseldamise põhimõtte rikkumine. Ühesõnaga, teine ​​vorm ei tohiks esimese olemasolust midagi teada ja, veelgi enam, ei tohiks seda mõjutada.

Selle probleemi lahendus on üsna lihtne. Vaatame otse koodi. Kujundajas loome põhivormi (see käivitatakse rakenduse käivitumisel). Paneme ühe Tekstikast, Silt Ja Nupp.

Nupule vajutades avaneb teine ​​vorm ning põhivormi tekstiväljalt kantakse tekst teise vormi tekstiväljale. Esialgu näeb teine ​​vorm välja selline:

Sarnaselt esimesele on sellel samad juhtnupud. Meil pole rohkem vaja. Rakenduse sisenemispunkt käivitab põhivormi:

Süsteemi kasutamine; kasutades System.Collections.Generic; kasutades System.Linq; kasutades System.Windows.Forms; nimeruum From1FormTo2 ( staatiline klass Programm ( // Rakenduse peamine sisenemispunkt. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

Peamine vormikood näeb välja selline:

Süsteemi kasutamine; kasutades System.Collections.Generic; kasutades System.ComponentModel; kasutades System.Data; kasutades System.Drawing; kasutades System.Linq; kasutades System.Text; kasutades System.Windows.Forms; nimeruum From1FormTo2 ( avalik osaklass MainForm: Vorm ( //teine ​​vorm SecondForm secondForm; //konstruktor public MainForm() ( InitializeComponent(); ) //andmeedastussündmuste töötleja //peavormilt teisele privaatsele voidile btn_mainForm_Click(object saatja, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData());

Seetõttu ärge unustage nuppu sündmusega ühendada Klõpsake. Siin põhivormi klassis on põld SecondForm secondForm, mis esindab teist vormiobjekti. Kui klõpsate nupul "Esita", luuakse teine ​​vorm (kutsutakse välja ülekoormatud konstruktor, loome selle hiljem) ja käivitatakse meetodil ShowDialog(). Sel juhul sobib see meetod meile. Peale selle kontrollime kindlasti, kas teine ​​vorm suleti, kuid klõpsas selle nupul. Kui teisel vormil klõpsati nuppu, siis esimene vorm peaks teise vormi andmeid vastu võtma. See juhtub meetodi kutsumisega ReturnData() teisel kujul.

Nüüd on kõige huvitavam osa teise vormi kood:

Süsteemi kasutamine; kasutades System.Collections.Generic; kasutades System.ComponentModel; kasutades System.Data; kasutades System.Drawing; kasutades System.Linq; kasutades System.Text; kasutades System.Windows.Forms; nimeruum From1FormTo2 ( public partial class SecondForm: Vorm ( //ülekoormatud konstruktor public SecondForm(stringandmed) ( InitializeComponent(); tb_secondForm.Text = data; ) //andmeedastussündmuse töötleja //teisest vormist peamisse privaatne tühimik btn_secondForm_Click (objekti saatja, EventArgs e) ( this.DialogResult = DialogResult.OK; ) //avalik meetod juurdepääsuks //selle vormi avaliku stringi tekstiväljale ReturnData() ( return (tb_secondForm.Text.Trim()); ) ) )

Nagu näete, on üks konstruktori ülekoormus, mis aktsepteerib stringitüüpi. Pidage meeles, et proovime teksti tekstikastist üle kanda. Konstruktoris plaanitakse komponendid lähtestada ja tekstivälja tekst seatakse esimeselt vormilt edastatavale väärtusele. Järgmiseks üritusele registreerudes Klõpsake teise vormi nupu jaoks lõime töötleja btn_secondForm_Click, mis simuleerib mis tahes dialoogiboksi nupu "Ok" toimimist. Seega, klõpsates (teise vormi) nupul “Esita”, täidame tingimuse

(secondForm .DialogResult == DialogResult .OK)

Esimene vorm, seega kutsudes meetodit secondForm.ReturnData(), määrame esimese vormi tekstivälja väärtuseks teise vormi tekstivälja.

Arvan, et selle meetodi toimimine ei vaja enam selgitusi. See lihtsalt tagastab teksti ühelt tekstiväljalt, hoides selle privaatsena.

Selle tulemusena kandsime andmed üle teisele vormile esimesest ja teisest esimesest ilma kapseldamise põhimõtteid rikkumata.

Proovige sisestada esimese vormi tekstiväljale tekst "aaa" ja klõpsata nuppu. Seda teksti näete teise avaneva vormi tekstiväljal. Proovige muuta tekstiks "aaa ppp" ja klõpsake nuppu. Näete, kuidas pärast teise vormi sulgemist see tekst põhivormi tekstiväljale ilmub.

Nüüd arvan, et saate andmeid vormide vahel õigesti üle kanda. Järgmises artiklis räägime sellest, kuidas seda ASP.NET-i rakendustes teha.

Viimati uuendatud: 31.10.2015

Projektile teise vormi lisamiseks paremklõpsake Solution Exploreri aknas projekti nimel ja valige Add->Windows Form...

Anname uuele vormile mõne nime, näiteks Vorm2.cs:

Seega oleme oma projektile lisanud teise vormi. Nüüd proovime rakendada kahe vormi vahelist interaktsiooni. Oletame, et esimene vorm kutsub nuppu klõpsates teist vormi. Esmalt lisame nupp esimesele vormile Form1 ja topeltklõpsake nuppu, et minna koodifaili. Seega suunatakse meid nupu klõpsusündmuste töötlejasse, mis luuakse vaikimisi pärast nupu topeltklõpsamist:

Privaatne void nupp1_Click(objekti saatja, EventArgs e) ( )

Nüüd lisame sellele teise vormi kutsumise koodi. Meie teist vormi nimetatakse Vorm2, nii et kõigepealt loome selle klassi objekti ja seejärel selle ekraanil kuvamiseks kutsume meetodiks Show:

Privaatne void nupp1_Click(objekti saatja, EventArgs e) ( Vorm2 newForm = new Form2(); newForm.Show(); )

Nüüd teeme vastupidi – nii et teine ​​vorm mõjutab esimest. Kuigi teine ​​vorm ei tea esimese olemasolust. Selle parandamiseks peate mingil viisil edastama teabe esimese vormi kohta teisele vormile. Selleks anname konstruktoris vormile lingi.

Nii et liigume teise vormi juurde ja läheme selle koodi juurde – paremklõpsake vormil ja valige Vaata koodi. Praegu on see tühi ja sisaldab ainult konstruktorit. Kuna C# toetab meetodite ülekoormamist, saame luua mitmeid erinevate parameetritega meetodeid ja konstruktoreid ning olenevalt olukorrast ühe neist välja kutsuda. Niisiis, muudame teise vormi koodifaili järgmiseks:

Süsteemi kasutamine; kasutades System.Collections.Generic; kasutades System.ComponentModel; kasutades System.Data; kasutades System.Drawing; kasutades System.Linq; kasutades System.Text; kasutades System.Threading.Tasks; kasutades System.Windows.Forms; nimeruum HelloApp ( avalik osaline klass Vorm2: Vorm ( public Form2() ( InitializeComponent(); ) public Form2(Form1 f) ( InitializeComponent(); f.BackColor = Color.Yellow; ) ) )

Tegelikult lisasime siia just uue konstruktori avaliku Form2(Form1 f) , milles saame esimese vormi ja määrame selle tausta kollaseks. Liigume nüüd edasi esimese vormi koodi juurde, kus kutsusime teise vormi ja muudame selle järgmiseks:

Privaatne void nupp1_Click(objekti saatja, EventArgs e) ( Vorm2 newForm = new Vorm2(this); newForm.Show(); )

Kuna antud juhul tähistab märksõna see viidet aktiivsele objektile - objektile Form1, siis teise vormi loomisel võtab ta selle (lingi) vastu ja juhib selle kaudu esimest vormi.

Nüüd, peale nupu klõpsamist, luuakse teine ​​vorm, mis muudab koheselt esimese vormi värvi.

Samuti saame luua praegusel kujul objekte:

Privaatne void nupp1_Click(objekti saatja, EventArgs e) ( Vorm1 uusvorm1 = uus vorm1(); uusvorm1.näita(); vorm2 uusvorm2 = uus vorm2(uus vorm1); uus vorm2.näita(); )

Mitme vormiga töötades tuleb arvestada, et üks neist on peamine – mis käivitatakse failis Program.cs esimesena. Kui meil on korraga avatud hulk vorme, siis peamise sulgemisel sulgub kogu rakendus ja koos sellega ka kõik muud vormid.

Administraatori poolt

C# õppimine on aeglane. kuid see jätkub ustavalt. Just hiljuti ma
tõi näite, kuidas Visual C#-s ühelt vormilt teist avada. Põhimõtteliselt on kõik lihtne.

Täna ilmus järgmine ülesanne: käivitada rakenduse põhivormilt modaalvorm, mille sulgemisel peab see vorm edastama osa andmeid (tekst, atribuutide väärtused jne) põhivormi juhtelementidele. Eelmises vormide postituses kirjeldatud meetodil ei ole seda probleemi võimalik lahendada, kuna sel juhul loome lihtsalt uue vormiobjekti uute väärtustega kõigi omaduste jaoks. Õnneks on C#-l imeline prügikorjaja... Asi pole aga kogujas, vaid selles, kuidas C#-s lapsvorm avada ja sealt siis põhivormile tagasi saada?

Alustuseks määrame algsed (algsed) andmed.

Niisiis. Meil on peamine taotlusvorm:

See vorm sisaldab ka tekstikasti nimega TBDialog ja nuppu Nupp, millel peaksime klõpsama:

  1. Edastage atribuudi Text väärtus TBDialogist TBMaini;
  2. Sule fDialog;

Vaatame nüüd kogu protsessi järjekorras.

Esiteks tasub alati meeles pidada, et vaikimisi on kõikidele C# atribuutidele, muutujatele ja meetoditele määratud modifikaator privaatne– seega, et jõuda teiselt vormilt esimese juhtelemendi juurde, peame määrama TBMaini modifikaatori avalik omapäi. Selleks valige vormikujundajas element TBMain, minge omaduste aknasse ja muuta kinnisvara väärtust Modifikaatorid Koos privaatne peal avalik

Nüüd on TBMain muudes objektides nähtav. Liigume edasi. Vormi modaalrežiimis avamiseks peame meetodi ShowDialog() jaoks kasutama ühte kahest võimalusest:

public DialogResult ShowDialog() ; public DialogResult ShowDialog(IWin32Window omanik) ;

Esimesel juhul kuvab meetod vormi modaalse dialoogiboksina, mille omanikuks on määratud praegune aktiivne aken, ja teisel juhul saame iseseisvalt määrata, milline vorm saab meie modaalakna omanikuks.

Näiteks kasutame ShowDialog() meetodi teist versiooni ja näitame teist vormi modaalselt. Selleks kirjutame järgmise:

Siin kasutasin uuesti märksõna see , mis osutab praegusele objektile, st. määrake põhivorm omanikuks ( fMain). Liigume nüüd otse oma probleemi lahendamise juurde ja vastame küsimusele: kuidas väärtust ühelt vormilt teisele üle kanda? Igal juhtelemendil on märkimisväärne omadus Omanik – mis viitab vanemale:

Nüüd saate projekti käivitada ja veenduda, et alamvormi tekstikasti tekst kandub ideaalselt esimese tekstikasti. Igaks juhuks postitan näites käsitletud projekti lähtekoodi.

Vaatamata sellele, et minu arvamus Microsofti Visual Studio kohta on endiselt sama, tuleb vahel sellega midagi ette võtta. Kui leppida sellega, et kirjutame tegelikult mitte C++-s, vaid nn C++/CLI-s, siis tuttavate visuaalsete komponentidega töötamine ei erine niisama nendesamade Borlandi keskkondadest. Kuid see võib Builderiga võrreldes probleeme tekitada. Vaatleme 3 tüüpilist olukorda rohkem kui ühte vormi sisaldava rakendusega töötamisel Näidiskeskkond on tasuta Visual C++ 2010 Express, eeldatakse, et põhivormil on vaikenimi Form1.

Näide vormi konstrueerimisest ja programmilisest kutsumisest

Seda koodi saab käivitada näiteks põhivormil Vorm1 nuppu klõpsates.

Vorm^vorm2 = gcnew Vorm(); Nupp^ nupp2 = gcnew Button(); nupp2->Tekst = L"OK"; nupp2->Asukoht = Punkt(10,10); vorm2->Tekst = L"Minu aken"; vorm2->AbiButton = tõene; form2->FormBorderStyle = Süsteem::Windows::Forms::FormBorderStyle::FixedDialog; vorm2->StartPosition = VormStartPosition::CenterScreen; vorm2->Juhtelemendid->Lisa(nupp2); vorm2->ShowDialog();

Programmiliselt loodud nupunupu2 klikitöötleja lisamiseks kirjutage lihtsalt enne koodi viimast rida:

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

Enne meetodi form2->ShowDialog() või vorm2->Show() väljakutsumist;

Sel juhul asub töötleja kood praeguses moodulis Form1.h:

Privaatne: System::Void button2_Click(Süsteem::Objekt^ saatja, Süsteem::EventArgs^ e) ( Message Box::Show("Siin"); )

Kutsuge põhivormilt välja mõni muu vorm

Valige menüüst Projekt - Lisa uus element - Vorm - nimi Vorm2

Lisame operaatori

#include "Vorm2.h"

enne esimest nimeruumi failis Form1.h (see tähendab faili alguses).

Lisame kursori klassi eksemplarile klassi Form1 avalikku sektsiooni:

Vorm2^F2;

Lisame koodi, kuhu peame looma ja kutsuma teise vormi:

F2=gcnewForm2(); F2->Näita();

Teise vormi programmiliseks kustutamiseks sobib järgmine kood:

Kustuta F2;

Tuleb märkida, et osuti salvestab ainult ühe vormi aadressi, selle, mis loodi viimati. Kui loome selle koodi abil järjest mitu vormi, kustutatakse ainult viimane. Teise võimalusena proovige allpool kirjeldatud kujundite massiivi.

Kirjeldame vajalikud andmed vormiklassis Form1 (siinkohal Tabulaatori projekti nimi ja nimeruum, vajadusel asenda enda omaga):

Staatiline konst int MAX_FORMS = 100; //Maksimaalne vormide arv int FormCount; //Vormi loenduri massiiv ^F2; //Osukur vormide massiivile

Seejärel lähtestame andmed põhivormi sündmuse Laadi abil:

VormCount=0; F2 = gcnew massiiv (MAX_VORMID);

Seejärel rakendame koodi järgmise vormi loomiseks

If(FormCount Näita(); ) else MessageBox::Show("Liiga palju vorme!");

ja selle eemaldamine:

Kui (FormCount) (kustuta F2; FormCount--; )

Kui tahame luua alamvorme mitte eraldi, vaid emavormi sees, siis peame vormi1 atribuutides märkima, et tegemist on esivanemaga (määrake atribuut IsMdiParent = true) ja enne alamvormi näitamist, kasutades F2->Show() operaator, märkige see alamvormiks Form1:

F2->MdiParent = see;

Vanemvormi meetodi kutsumine alamvormist

Vaevalt saame ilma .cpp-failideta hakkama, mis pole halb – .h-failidesse koodi kirjutamine rikub üldiselt õiget C-süsteemi :)

Kirjeldame protsessi samm-sammult.

1) Vorme on 2 - Vorm1 ja Vorm2, vormil 1 on Nupp (nupp1, avab teise vormi) ja Silt (silt1, siin muudame teksti). Vormil 2 – nupul 1 muutub klõpsamisel sildi1 tekst.

2) Kuna meil peab olema juurdepääs teisele esimesest vormist ja teisest esimesest, tekib ristviidete probleem (kui vorm1.h viitab vormile 2.h, mis omakorda viitab vormile 1.h) . Selle vältimiseks teisaldame esimese vormi koodi (vorm1), millel on juurdepääs teisele vormile (vorm2), .h-failist .cpp-faili. Seega peate looma faili Form1.cpp.

3) Deklareerige vormis Form1.h avalik Set meetod, et saaksite sildi1 teksti muuta (koodi saab kirjutada faili lõppu, pärast #pragma endregion):

Avalik: void Set(String^ tekst) ( silt1->Tekst = tekst; )

4) Failis Form2.h kaasame Form1.h (alguses):

#include "Vorm1.h"

ja looge konstruktor, mis aktsepteerib ja salvestab lingi esimesele vormile edasiseks kasutamiseks:

Vorm2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //saate kirjutada lingi kohe alla: private: Form1^ parentForm;

5) Klõpsates vormis 2 nuppu, kutsume esile lähtevormi Set meetodi:

Privaatne: System::Void button1_Click(System::Object^ saatja, System::EventArgs^ e) ( parentForm->Set("tere vormist2"); parentForm->Show(); this->Hide(); )

6) Jääb üle avada teine ​​vorm esimesel kujul. Selleks viime nupuklõpsukäitleja vormist Form1.h vormingusse Form1.cpp ja .h faili jätame ainult selle deklaratsiooni.