Jak otevřít další z jednoho formuláře. Přidávání formulářů. Interakce mezi formuláři. Příklad sestavení a programového volání formuláře

Otázka řešená v tomto článku se pravděpodobně bude týkat tématu budování aplikační architektury, a nikoli konkrétně uvažovaného problému. Přenos dat z jednoho formuláře do druhého není vůbec náročný. K tomu stačí ovládací prvek, jehož data chceme získat, otevřít, tedy označit modifikátorem public. Také je možná jiná možnost. Například v první formě vytvoříme objekt druhé formy předáním odkazu na sebe konstruktoru, tedy předáním odkazu na první z prvního formuláře do druhého
SecondForm secondForm = new SecondForm(this);
Než to uděláte, měli byste se přirozeně postarat o vytvoření přetížení pro konstruktor druhého formuláře.

A tato metoda je docela běžná. Svou jednoduchostí však nese mnoho potenciálních problémů, z nichž hlavním je porušení principu zapouzdření. Stručně řečeno, druhá forma by neměla vědět nic o existenci první a tím spíše by ji neměla mít možnost ovlivnit.

Řešení tohoto problému je celkem jednoduché. Podívejme se přímo na kód. Tvoříme v návrháři hlavní formulář(spustí se při spuštění aplikace). Položme jeden Textové pole, Označení A Knoflík.

Kliknutím na tlačítko se otevře druhý formulář a text z textové pole hlavní formulář se přenese do textového pole druhého formuláře. Zpočátku vypadá druhý formulář takto:

Podobně jako u prvního má stejné ovládání. Víc nepotřebujeme. Vstupní bod aplikace spustí hlavní formulář:

Použití systému; pomocí System.Collections.Generic; pomocí System.Linq; pomocí System.Windows.Forms; jmenný prostor From1FormTo2 ( statická třída Program ( // Hlavní vstupní bod pro aplikaci. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

Hlavní kód formuláře vypadá takto:

Použití systému; pomocí System.Collections.Generic; pomocí System.ComponentModel; pomocí System.Data; pomocí System.Drawing; pomocí System.Linq; pomocí System.Text; pomocí System.Windows.Forms; jmenný prostor From1FormTo2 ( veřejná částečná třída MainForm: Form ( //druhá forma SecondForm secondForm; //konstruktor public MainForm() ( InitializeComponent(); ) //obslužný program události přenosu dat //z hlavního formuláře do druhého soukromého void btn_mainForm_Click(object odesílatel, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData(); ) ) )

V souladu s tím nezapomeňte tlačítko připojit k události Klikněte. Zde ve třídě hlavního formuláře je pole SecondForm secondForm, představující objekt druhého formuláře. Po kliknutí na tlačítko „Odeslat“ se vytvoří druhý formulář (zavolá se přetížený konstruktor, vytvoříme jej později) a spustí se metodou ShowDialog(). V tomto případě je pro nás tato metoda vhodná. Poté se navíc ujistíme, že zkontrolujeme, zda byl druhý formulář uzavřen, ale kliklo se na jeho tlačítko. Pokud bylo kliknuto na tlačítko na druhém formuláři, měl by první formulář přijmout data z druhého formuláře. To se děje voláním metody ReturnData() ve druhé podobě.

Nyní je nejzajímavější část kódu druhého formuláře:

Použití systému; pomocí System.Collections.Generic; pomocí System.ComponentModel; pomocí System.Data; pomocí System.Drawing; pomocí System.Linq; pomocí System.Text; pomocí System.Windows.Forms; jmenný prostor From1FormTo2 ( veřejná částečná třída SecondForm: Form ( //přetížený konstruktor public SecondForm(data string) ( InitializeComponent(); tb_secondForm.Text = data; ) //obslužný program události přenosu dat //z druhého formuláře do hlavního private void btn_secondForm_Click (odesílatel objektu, EventArgs e) ( this.DialogResult = DialogResult.OK; ) // veřejnou metodou pro přístup k // textovému poli tohoto formuláře veřejný řetězec ReturnData() ( return (tb_secondForm.Text.Trim()); ) ) )

Jak můžete vidět, existuje přetížení jediného konstruktoru, který přijímá typ řetězce. Pamatujte, že se snažíme přenést text z textového pole. V konstruktoru se naplánuje inicializace komponent a text textového pole se nastaví na přenášenou hodnotu z prvního formuláře. Dále přihlášením k odběru události Klikněte pro tlačítko druhého formuláře jsme vytvořili handler btn_secondForm_Click, která simuluje činnost tlačítka „OK“ libovolného dialogového okna. Podmínku tedy provedeme kliknutím na tlačítko „Odeslat“ (druhého formuláře).

(secondForm .DialogResult == DialogResult .OK)

První formulář tedy volá metodu secondForm.ReturnData(), nastavíme textové pole prvního formuláře na hodnotu textového pole druhého formuláře.

Práce tato metoda, myslím, že už nepotřebuje vysvětlení. Jednoduše vrátí text z jednoho textového pole, přičemž jej zachová soukromé.

V důsledku toho jsme přenesli data do druhého formuláře z prvního a z druhého do prvního, aniž bychom porušili zásady zapouzdření.

Zkuste zadat text „aaa“ do textového pole prvního formuláře a kliknout na tlačítko. Tento text uvidíte v textovém poli ve druhém formuláři, který se otevře. Zkuste změnit text na „aaa ppp“ a klikněte na tlačítko. Uvidíte, jak se po zavření druhého formuláře tento text objeví v textovém poli hlavního formuláře.

Nyní si myslím, že budete moci přenášet data mezi formuláři správněji. V příštím článku si povíme, jak na to v aplikacích ASP.NET.

Poslední aktualizace: 31. 10. 2015

Chcete-li do projektu přidat další formulář, klikněte pravým tlačítkem myši na název projektu v okně Průzkumník řešení a vyberte Přidat->Windows Form...

Pojmenujme nový formulář, např. Form2.cs:

Takže jsme do našeho projektu přidali druhý formulář. Nyní se pokusíme implementovat interakci mezi dvěma formami. Řekněme, že první formulář po kliknutí na tlačítko zavolá druhý formulář. Nejprve přidejte tlačítko do prvního formuláře, Form1, a poklepáním na tlačítko přejděte do souboru kódu. Dostaneme se tedy k obslužné rutině události kliknutí tlačítka, která se ve výchozím nastavení vytvoří po dvojitém kliknutí na tlačítko:

Private void button1_Click(object sender, EventArgs e) ( )

Nyní k němu přidáme kód pro volání druhého formuláře. Náš druhý formulář se nazývá Form2, takže nejprve vytvoříme objekt této třídy a poté jej zobrazíme na obrazovce zavoláním metody Show:

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

Nyní udělejme opak – aby druhá forma ovlivnila první. Zatímco druhá forma o existenci první neví. Chcete-li to opravit, musíte nějak přenést informace o prvním formuláři do druhého formuláře. Využijeme k tomu předání odkazu na formulář v konstruktoru.

Přejdeme tedy k druhému formuláři a přejdeme k jeho kódu – klikneme na formulář pravým tlačítkem a vybereme Zobrazit kód. Prozatím je prázdný a obsahuje pouze konstruktor. Protože C# podporuje přetěžování metod, můžeme vytvořit několik metod a konstruktorů s různými parametry a jednu z nich volat v závislosti na situaci. Změňme tedy soubor kódu druhého formuláře na následující:

Použití systému; pomocí System.Collections.Generic; pomocí System.ComponentModel; pomocí System.Data; pomocí System.Drawing; pomocí System.Linq; pomocí System.Text; pomocí System.Threading.Tasks; pomocí System.Windows.Forms; jmenný prostor HelloApp ( veřejná částečná třída Form2: Form ( public Form2() ( InitializeComponent(); ) public Form2(Form1 f) ( InitializeComponent(); f.BackColor = Color.Yellow; ) ) )

Ve skutečnosti jsme sem přidali nový konstruktér public Form2(Form1 f) ve kterém získáme první formulář a nastavíme jeho pozadí na žluté. Nyní přejdeme ke kódu prvního formuláře, kde jsme zavolali druhý formulář a změňme jej na následující:

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

Protože v tomto případě klíčové slovo this představuje odkaz na aktuální objekt - objekt Form1, tak při vytváření druhého formuláře jej přijme (odkaz) a bude přes něj ovládat první formulář.

Nyní se po kliknutí na tlačítko vytvoří druhý formulář, který okamžitě změní barvu prvního formuláře.

Můžeme také vytvořit objekty aktuálního tvaru:

Private void button1_Click(odesílatel objektu, EventArgs e) ( Form1 newForm1 = new Form1(); newForm1.Show(); Form2 newForm2 = new Form2(newForm1); newForm2.Show(); )

Při práci s více formuláři je třeba počítat s tím, že jeden z nich je hlavní - který se spouští jako první v souboru Program.cs. Pokud máme současně otevřenou hromadu formulářů, tak když zavřeme ten hlavní, zavře se celá aplikace a s ní i všechny ostatní formuláře.

Navzdory tomu, že můj názor na Visual Studio od Microsoftu je stále stejný, občas na něm musíte něco udělat. Pokud se smíříme s tím, že ve skutečnosti píšeme ne v C++, ale v tzv. C++/CLI, nebude se práce se známými vizuálními komponentami tolik lišit od stejných prostředí Borland. Ve srovnání s Builderem ale může dělat problémy Uvažujme 3 typické situace práce s aplikací obsahující více formulářů Příklad prostředí je bezplatný Visual C++ 2010 Express, předpokládá se, že hlavní formulář má výchozí název Form1.

Příklad sestavení a programového volání formuláře

Tento kód lze spustit například kliknutím na tlačítko v hlavním formuláři Form1.

Form^form2 = gcnew Form(); Tlačítko^ tlačítko2 = gcnew Tlačítko(); button2->Text = L"OK"; button2->Umístění = Bod(10,10); form2->Text = L"Moje okno"; form2->HelpButton = true; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; formulář2->Ovládací prvky->Přidat(tlačítko2); form2->ShowDialog();

Chcete-li přidat obslužný program kliknutí pro programově generované tlačítko button2, stačí napsat před poslední řádek kódu:

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

Před voláním metody form2->ShowDialog() nebo form2->Show();

V tomto případě je kód handleru umístěn v aktuálním modulu Form1.h:

Private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) ( MessageBox::Show("Here"); )

Vyvolejte jiný formulář z hlavního formuláře

V nabídce vyberte Projekt - Přidat nový prvek- Formulář - název Formulář2

Přidáme operátora

#include "Form2.h"

před prvním jmenným prostorem ve Form1.h (tj. na samém začátku souboru).

Pojďme zahrnout ukazatel na instanci třídy do veřejné sekce třídy Form1:

Form2^F2;

Přidejme kód tam, kde potřebujeme vytvořit a zavolat druhý formulář:

F2=gcnewForm2(); F2->Zobrazit();

Chcete-li programově odstranit druhý formulář, je vhodný následující kód:

Smazat F2;

Je třeba poznamenat, že ukazatel ukládá adresu pouze jednoho formuláře, toho, který byl vytvořen jako poslední. Pokud pomocí tohoto kódu vytvoříme postupně několik formulářů, smaže se pouze poslední. Případně vyzkoušejte pole tvarů popsané níže.

Popišme si potřebná data ve formulářové třídě Form1 (zde název a jmenný prostor projektu Tabulator v případě potřeby nahraďte vlastním):

Static const int MAX_FORMS = 100; //Maximální počet formulářů int FormCount; //Pole čítače formulářů ^F2; //Ukazatel na pole formulářů

Poté data inicializujeme pomocí události Load hlavního formuláře:

FormCount=0; F2 = pole gcnew (MAX_FORMS);

Poté implementujeme kód pro vytvoření dalšího formuláře

If(FormCount Ukázat(); ) else MessageBox::Show("Příliš mnoho formulářů!");

a jeho odstranění:

If (FormCount) ( smazat F2; FormCount--; )

Pokud chceme vytvořit podřízené formuláře nikoli samostatně, ale uvnitř nadřazeného formuláře, pak ve vlastnostech Form1 musíme uvést, že se jedná o „předchůdce“ (nastavte vlastnost IsMdiParent = true) a před zobrazením podřízeného formuláře pomocí Operátor F2->Show(), označte jej jako podřízený Form1:

F2->MdiParent = toto;

Volání metody nadřazeného formuláře z podřízeného formuláře

Těžko se obejdeme bez použití souborů .cpp, což není špatné - psaní kódu v souborech .h obecně narušuje správný systém C :)

Pojďme si proces popsat krok za krokem.

1) Jsou 2 formuláře - Form1 a Form2, na Form1 je Button (button1, otevře druhý formulář) a Label (label1, zde změníme text). Na Formuláři2 - tlačítko1 se po kliknutí změní text v label1.

2) Protože potřebujeme mít přístup k druhému z prvního formuláře a ke druhému k prvnímu, vyvstane problém s křížovými odkazy (když Form1.h odkazuje na Form2.h, který zase odkazuje do Form1.h). Abychom tomu zabránili, přesuneme kód prvního formuláře (Form1), který bude mít přístup k druhému formuláři (Form2), ze souboru .h do souboru .cpp. Musíte tedy vytvořit soubor Form1.cpp.

3) Deklarujte veřejnou metodu Set ve Form1.h, abyste mohli změnit text label1 (kód lze napsat na konec souboru, za #pragma endregion):

Veřejné: void Set(String^ text) ( label1->Text = text; )

4) Do souboru Form2.h zahrneme Form1.h (na začátku):

#include "Form1.h"

a vytvořte konstruktor, který přijme a uloží odkaz na první formulář pro další použití:

Form2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //můžete napsat odkaz hned níže: private: Form1^ parentForm;

5) Po kliknutí na tlačítko ve Formuláři2 zavoláme metodu Set nadřazeného formuláře:

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

6) Zbývá otevřít druhý formulář v prvním formuláři. Za tímto účelem přesuneme obslužnou rutinu kliknutí na tlačítko z Form1.h do Form1.cpp a v souboru .h ponecháme pouze jeho deklaraci.

Někdy je nutné přistupovat k prvkům jednoho formuláře z jiného během provádění programu. Existuje například formulář Form1, z něj otevřeme další Formulář2 a nyní, pracujeme ve Formuláři2, potřebujeme přistupovat k prvkům nadřazeného formuláře Form1. Našel jsem několik způsobů, jak to udělat.

1. způsob. Předání odkazu na veřejnou proměnnou.

Namespace WindowsApplication1 ( veřejná částečná třída Form1: Form ( public Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // send odkaz na tlačítko ve tvaru Form2 frm.ShowDialog(); ) ) )

Ve formuláři2 bude nyní proměnná, na kterou byl předán odkaz, odpovídat button1 z formuláře1

Namespace WindowsApplication1 ( veřejná částečná třída Form2: Form ( public Button but1; // tato proměnná bude obsahovat odkaz na tlačítko1 z Form1 public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1. Text = "test"; // změňte text na tlačítku button1 formuláře1 ) ) )

2. způsob. Předání odkazu na podřízený formulář.

Podstata je přibližně stejná v 1. způsobu. Při otevření Form2 do něj předáme odkaz na prvek, který plánujeme později změnit.

Namespace WindowsApplication1 ( veřejná částečná třída Form1: Form ( public Form1() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(this.button1); // předání odkazu na tlačítko do formuláře Form2 frm.ShowDialog(); ) ) )

Nyní ve Formuláři2 musíme vytvořit proměnnou, která bude obsahovat odkaz na toto tlačítko a přes ni přistoupíme k tlačítku na Formuláři1 (řádky 5,7,9 a 15).

Namespace WindowsApplication1 ( veřejná částečná třída Form2: Form ( private Button but1; // tato proměnná bude obsahovat odkaz na tlačítko button1 z formuláře Form1 public Form2(Button but) // získat odkaz na tlačítko v proměnné but ( but1 = but; // nyní but1 bude odkaz na tlačítko button1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( but1.Text = "test"; // změna textu na button button1 formuláře1 ) ) )

3. způsob. Přístup k celému nadřazenému formuláři.

Chcete-li to provést, musíte provést změny v několika souborech, ale zároveň budeme mít přístup ke všem prvkům nadřazeného formuláře a nebudeme muset předávat odkaz na každý prvek, jako v metodě 1.

Krok 1. V souboru Program.cs vytvořte veřejnou proměnnou f1 (řádek 5).

Jmenný prostor WindowsApplication1 ( statická třída Program ( public static Form1 f1; // proměnná, která bude obsahovat odkaz na formulář Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1( ) ) ) )

Krok 2. Otevírací Form1.Designer.cs a v něm u prvků, ke kterým bude potřeba přistupovat z jiného formuláře, měníme soukromé na veřejnost. Udělejme například tlačítko1 na Form1 dostupné pro změny.

Public System.Windows.Forms.Button button1; // nahrazeno private za public

Krok 3. Při vytváření formuláře1 přiřadíme proměnné f1 odkaz na tento formulář (řádek 7)

Namespace WindowsApplication1 ( veřejná částečná třída Form1: Form ( public Form1() ( Program.f1 = this; // nyní f1 bude odkaz na formulář Form1 InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Form2 frm = new Form2(); frm.ShowDialog(); ) ) )

Krok 4. Nyní z jakéhokoli formuláře nebo z jakékoli třídy můžete přistupovat k prvku button1 umístěnému na Form1 takto: Program.f1.button1. Nechte například tlačítko na formuláři2 změnit text tlačítka na formuláři1:

Namespace WindowsApplication1 ( veřejná částečná třída Form2: Form ( public Form2() ( InitializeComponent(); ) private void button1_Click(object sender, EventArgs e) ( Program.f1.button1.Text = "test"; // Změna textu na tlačítko formuláře Form1 ) ) )

Od admin.

Učení C# je pomalé. ale věrně pokračuje. Zrovna nedávno já
uvedl příklad, jak otevřít další z jednoho formuláře ve Visual C#. V zásadě je vše jednoduché.

Dnes se objevil následující úkol: spustit modální formulář z hlavního formuláře aplikace, po zavření musí tento formulář předat některá data (text, hodnoty vlastností atd.) ovládacím prvkům na hlavním formuláři. Tento problém není možné vyřešit pomocí metody popsané v předchozím příspěvku o formulářích, protože v tomto případě jednoduše vytvoříme nový objekt formuláře s novými hodnotami pro všechny vlastnosti. Naštěstí C# má úžasný garbage collector... Ale nejde o kolektor, ale jak otevřít podřízený formulář v C# a pak se z něj dostat zpět do hlavního formuláře?

Pro začátek si nastavíme počáteční (počáteční) data.

Tak. Máme hlavní formulář žádosti:

Tento formulář také obsahuje TextBox s názvem TBDialog a tlačítko Button, na které bychom měli kliknout:

  1. Předat hodnotu Vlastnosti textu z TBDialog do TBMain;
  2. Zavřít fDialog;

Nyní se podívejme na celý proces v pořádku.

Za prvé, vždy stojí za to pamatovat na to, že ve výchozím nastavení jsou všem vlastnostem, proměnným a metodám v C# přiřazen modifikátor soukromé– proto, abychom se dostali z druhého formuláře do ovládání prvního, musíme nastavit modifikátor pro TBMain veřejnost na vlastní pěst. Chcete-li to provést, vyberte prvek TBMain v návrháři formulářů, přejděte do okna vlastností a změnit hodnotu nemovitosti Modifikátory S soukromé na veřejnost.

Nyní bude TBMain viditelný v jiných objektech. Pokračujme. Abychom mohli otevřít formulář v modálním režimu, musíme použít jednu ze dvou možností pro metodu ShowDialog():

public DialogResult ShowDialog() ; public DialogResult ShowDialog(vlastník IWin32Window) ;

V prvním případě metoda zobrazí formulář jako modální dialogové okno s aktuálním aktivním oknem nastaveným jako vlastník a ve druhém můžeme nezávisle určit, který formulář se stane vlastníkem našeho modálního okna.

Použijme například druhou verzi metody ShowDialog() a ukažme druhý formulář modálně. K tomu napíšeme následující:

Zde jsem opět využil klíčové slovo tento , který ukazuje na aktuální objekt, tzn. nastavit hlavní formulář jako vlastník ( fHlavní). Nyní přejděme přímo k řešení našeho problému a odpovězme na otázku: jak předávat hodnotu z jedné formy do druhé? Každý ovládací prvek má pozoruhodnou vlastnost Majitel – který ukazuje na rodiče:

Nyní můžete spustit projekt a ujistit se, že text z TextBox na podřízeném formuláři se perfektně přenese do TextBox na prvním z nich. Pro jistotu zveřejňuji zdrojový kód projektu, o kterém se mluví v příkladu.