Hur man öppnar en annan från ett formulär. Lägger till formulär. Interaktion mellan former. Ett exempel på att konstruera och programmera ett formulär

Frågan som tas upp i den här artikeln är mer sannolikt att relatera till ämnet att bygga en applikationsarkitektur, och inte specifikt till problemet som övervägs. Att överföra data från en form till en annan är inte alls svårt. För att göra detta räcker det att göra kontrollen vars data vi vill skaffa öppen, det vill säga markera den med den offentliga modifieraren. Ett annat alternativ är också möjligt. Till exempel, i den första formen skapar vi ett objekt av den andra formen genom att skicka en referens till oss själva till konstruktorn, det vill säga genom att skicka en referens till den första från den första formen till den andra
SecondForm secondForm = new SecondForm(this);
Naturligtvis, innan du gör detta, bör du ta hand om att skapa en överbelastning för konstruktören av den andra formen.

Och denna metod är ganska vanlig. Men med sin enkelhet har den många potentiella problem, det viktigaste är ett brott mot principen om inkapsling. Med ett ord, den andra formen borde inte veta något om existensen av den första och, ännu mer, inte kunna påverka den.

Lösningen på detta problem är ganska enkel. Låt oss titta direkt på koden. Vi skapar i designern huvudform(det kommer att startas när programmet startar). Låt oss lägga en Textruta, Märka Och Knapp.

Genom att klicka på knappen öppnas det andra formuläret och texten från textfält huvudformuläret kommer att överföras till textfältet i det andra formuläret. Till en början ser den andra formen ut så här:

I likhet med den första har den samma kontroller. Vi behöver inte mer. Ansökningsstartpunkten startar huvudformuläret:

Använda System; använder System.Collections.Generic; använder System.Linq; använder System.Windows.Forms; namnutrymme From1FormTo2 ( static class Program ( // Huvudstartpunkten för applikationen. static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); ) ) )

Huvudformulärkoden ser ut så här:

Använda System; använder System.Collections.Generic; använder System.ComponentModel; använder System.Data; använder System.Drawing; använder System.Linq; använder System.Text; använder System.Windows.Forms; namnutrymme From1FormTo2 ( public partial class MainForm: Form ( //second form SecondForm secondForm; //constructor public MainForm() ( InitializeComponent(); ) //dataöverföringshändelsehanterare //från huvudformuläret till det andra privata void btn_mainForm_Click(object avsändare, EventArgs e) ( secondForm = new SecondForm(tb_mainForm.Text.Trim()); secondForm.ShowDialog(); if (secondForm.DialogResult == DialogResult.OK) tb_mainForm.Text = secondForm.ReturnData(); ) ) )

Glöm därför inte att ansluta knappen till evenemanget Klick. Här i huvudformklassen finns ett fält SecondForm secondForm, som representerar det andra formobjektet. När du klickar på knappen "Skicka" skapas ett andra formulär (den överbelastade konstruktorn anropas, vi skapar den senare) och startas med metoden ShowDialog(). I det här fallet är denna metod lämplig för oss. Dessutom ser vi efter detta till att kontrollera om det andra formuläret stängdes, men klickade på dess knapp. Om en knapp klickades på det andra formuläret, bör det första formuläret acceptera data från det andra. Detta sker genom att anropa metoden ReturnData() i den andra formen.

Nu är den mest intressanta delen koden för den andra formen:

Använda System; använder System.Collections.Generic; använder System.ComponentModel; använder System.Data; använder System.Drawing; använder System.Linq; använder System.Text; använder System.Windows.Forms; namnutrymme From1FormTo2 ( public partial class SecondForm: Form ( //overloaded constructor public SecondForm(string data) ( InitializeComponent(); tb_secondForm.Text = data; ) //dataöverföringshändelsehanterare //från den andra formen till den huvudsakliga privata tomrummet btn_secondForm_Click (objektavsändare, EventArgs e) ( this.DialogResult = DialogResult.OK; ) // offentlig metod för att komma åt // textfältet i detta formulär offentlig sträng ReturnData() (retur (tb_secondForm.Text.Trim()); ) ) )

Som du kan se finns det en enda konstruktoröverbelastning som accepterar en strängtyp. Kom ihåg att vi försöker överföra text från en textruta. I konstruktorn är komponenterna schemalagda att initialiseras och texten i textfältet sätts till det överförda värdet från det första formuläret. Därefter genom att prenumerera på evenemanget Klick för knappen i det andra formuläret skapade vi en hanterare btn_secondForm_Click, som simulerar funktionen för "Ok"-knappen i valfri dialogruta. Genom att klicka på knappen "Skicka" (i den andra formen) utför vi villkoret

(secondForm .DialogResult == DialogResult .OK)

Den första formen kallar därför metoden secondForm.ReturnData(), ställer vi in ​​textfältet för det första formuläret till värdet för textfältet i det andra formuläret.

Jobb den här metoden Jag tror inte längre kräver förklaring. Den returnerar helt enkelt texten från ett enda textfält, samtidigt som den håller den privat.

Som ett resultat överförde vi data till den andra formen från den första och från den andra till den första utan att bryta mot principerna för inkapsling.

Försök att skriva in texten "aaa" i textfältet i det första formuläret och klicka på knappen. Du kommer att se denna text i textfältet i det andra formuläret som öppnas. Prova att ändra texten till "aaa ppp" och klicka på knappen. Du kommer att se hur, efter att ha stängt det andra formuläret, denna text kommer att visas i huvudformulärets textfält.

Nu tror jag att du kommer att kunna överföra data mellan formulär mer korrekt. I nästa artikel kommer vi att prata om hur man gör det i ASP.NET-applikationer.

Senast uppdaterad: 2015-10-31

För att lägga till ytterligare ett formulär till projektet, högerklicka på projektnamnet i Solution Explorer-fönstret och välj Lägg till->Windows-formulär...

Låt oss ge den nya formen ett namn, till exempel, Form2.cs:

Så vi har lagt till en andra form till vårt projekt. Låt oss nu försöka implementera interaktion mellan två former. Låt oss säga att det första formuläret anropar det andra formuläret när du klickar på knappen. Låt oss först lägga till en knapp i det första formuläret, Form1, och dubbelklicka på knappen för att gå till kodfilen. Så vi kommer att tas till knappens klickhändelsehanterare, som skapas som standard efter att ha dubbelklickat på knappen:

Privat void button1_Click(objektavsändare, EventArgs e) ( )

Låt oss nu lägga till koden för att anropa det andra formuläret. Vår andra form heter Form2, så först skapar vi ett objekt av den här klassen, och för att sedan visa det på skärmen kallar vi Visa-metoden:

Privat void button1_Click(objektavsändare, EventArgs e) (Form2 newForm = new Form2(); newForm.Show(); )

Låt oss nu göra tvärtom - så att den andra formen påverkar den första. Medan den andra formen inte vet om existensen av den första. För att fixa detta måste du på något sätt överföra information om det första formuläret till det andra formuläret. För att göra detta kommer vi att använda att skicka en länk till formuläret i konstruktorn.

Så låt oss gå vidare till det andra formuläret och gå till dess kod - högerklicka på formuläret och välj Visa kod. För närvarande är den tom och innehåller bara en konstruktor. Eftersom C# stöder metodöverbelastning kan vi skapa flera metoder och konstruktörer med olika parametrar och anropa en av dem beroende på situationen. Så låt oss ändra kodfilen i det andra formuläret till följande:

Använda System; använder System.Collections.Generic; använder System.ComponentModel; använder System.Data; använder System.Drawing; använder System.Linq; använder System.Text; använda System.Threading.Tasks; använder System.Windows.Forms; namnutrymme HelloApp ( offentlig delklass Form2: Form ( public Form2() ( InitializeComponent(); ) public Form2(Form1 f) ( InitializeComponent(); f.BackColor = Color.Yellow; ) ) )

Vi har faktiskt precis lagt till här ny konstruktör public Form2(Form1 f) där vi får den första formen och sätter dess bakgrund till gul. Låt oss nu gå vidare till koden för det första formuläret, där vi kallade det andra formuläret och ändra det till följande:

Privat void button1_Click(objektavsändare, EventArgs e) (Form2 newForm = new Form2(this); newForm.Show(); )

Eftersom nyckelordet i det här fallet representerar en referens till det aktuella objektet - Form1-objektet, kommer det att ta emot det (länken) när det skapas det andra formuläret och styra det första formuläret genom det.

Nu, efter att ha klickat på knappen, skapas ett andra formulär, som omedelbart kommer att ändra färgen på det första formuläret.

Vi kan också skapa objekt av den nuvarande formen:

Privat void button1_Click(objektavsändare, EventArgs e) ( Form1 newForm1 = new Form1(); newForm1.Show(); Form2 newForm2 = new Form2(newForm1); newForm2.Show(); )

När du arbetar med flera formulär måste du ta hänsyn till att en av dem är den huvudsakliga - som lanseras först i filen Program.cs. Om vi ​​har ett gäng formulär öppna samtidigt, när vi stänger huvudet stängs hela applikationen och tillsammans med den alla andra formulär.

Trots att min åsikt om Microsofts Visual Studio fortfarande är densamma måste man ibland göra något åt ​​det. Om vi ​​kommer överens med det faktum att vi faktiskt inte skriver i C++, utan i det så kallade C++/CLI, kommer arbetet med välbekanta visuella komponenter inte att skilja sig så mycket från samma Borland-miljöer. Men det kan skapa problem, jämfört med Builder Låt oss överväga 3 typiska situationer för att arbeta med en applikation som innehåller mer än en form.Exempelmiljön är gratis Visual C++ 2010 Express, det antas att huvudformen har standardnamnet Form1.

Ett exempel på att konstruera och programmera ett formulär

Denna kod kan exekveras genom att till exempel klicka på en knapp i huvudformuläret Form1.

Form^form2 = gcnew Form(); Button^ button2 = gcnew Button(); knapp2->Text = L"OK"; knapp2->Plats = Point(10,10); form2->Text = L"Mitt fönster"; form2->HelpButton = sant; form2->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog; form2->StartPosition = FormStartPosition::CenterScreen; form2->Controls->Add(button2); form2->ShowDialog();

För att lägga till en klickhanterare för en programmatiskt genererad knappknapp2, skriv bara före den sista raden med kod:

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

Innan metoden form2->ShowDialog() eller form2->Show() anropas;

I det här fallet finns hanterarkoden i den aktuella modulen Form1.h:

Privat: System::Void button2_Click(System::Object^ avsändare, System::EventArgs^ e) ( MessageBox::Show("Here"); )

Ring ett annat formulär från huvudformuläret

I menyn väljer du Projekt - Lägg till nytt element- Form - namn Form2

Låt oss lägga till en operatör

#inkludera "Form2.h"

före det första namnområdet i Form1.h (det vill säga i början av filen).

Låt oss inkludera en pekare till klassinstansen i den offentliga delen av Form1-klassen:

Form2^F2;

Låt oss lägga till koden där vi behöver skapa och anropa det andra formuläret:

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

För att programmatiskt radera det andra formuläret är följande kod lämplig:

Ta bort F2;

Det bör noteras att pekaren lagrar adressen till endast ett formulär, det som skapades senast. Om vi ​​skapar flera formulär i följd med den här koden, kommer endast den sista att raderas. Alternativt kan du prova formmatrisen som beskrivs nedan.

Låt oss beskriva nödvändiga data i formulärklassen Form1 (här namnet och namnutrymmet för Tabulator-projektet, om nödvändigt, ersätt med ditt eget):

Statisk konstant int MAX_FORMS = 100; //Maximalt antal formulär int FormCount; //Format räknare array ^F2; //Pekare till en rad formulär

Sedan initierar vi data med hjälp av Load-händelsen i huvudformuläret:

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

Sedan kommer vi att implementera koden för att skapa nästa formulär

If(FormCount Show(); ) else MessageBox::Show("För många formulär!");

och dess borttagning:

If (FormCount) ( ta bort F2; FormCount--; )

Om vi ​​vill skapa underordnade formulär inte separat, utan i det överordnade formuläret, måste vi i egenskaperna för Form1 ange att det är en "förfader" (ställ in egenskapen IsMdiParent = true), och innan vi visar underformen med hjälp av F2->Show() operator, markera den som en underordnad Form1:

F2->MdiParent = detta;

Anropa en överordnad formulärmetod från ett underordnat formulär

Vi kan knappast klara oss utan att använda .cpp-filer, vilket inte är dåligt - att skriva kod i .h-filer bryter i allmänhet det korrekta C-systemet :)

Låt oss beskriva processen steg för steg.

1) Det finns 2 formulär - Form1 och Form2, på Form1 finns en knapp (knapp1, öppnar den andra formen) och Label (etikett1, här kommer vi att ändra texten). På Formulär2 - knapp1, när den klickas, ändras texten i etikett1.

2) Eftersom vi behöver ha tillgång från den första formen till den andra och från den andra till den första, kommer problemet med korsreferenser att uppstå (när Form1.h hänvisar till Form2.h, vilket i sin tur återigen hänvisar till till Form1.h) . För att undvika detta kommer vi att flytta koden för det första formuläret (Form1), som kommer att ha tillgång till det andra formuläret (Form2), från .h-filen till .cpp-filen. Därför måste du skapa en fil Form1.cpp.

3) Deklarera en public Set-metod i Form1.h så att du kan ändra texten i label1 (koden kan skrivas i slutet av filen, efter #pragma endregion):

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

4) I Form2.h-filen inkluderar vi Form1.h (i början):

#include "Form1.h"

och skapa en konstruktor som accepterar och sparar en länk till det första formuläret för vidare användning:

Form2(Form1^ parent) ( InitializeComponent(); parentForm = parent; ) //du kan skriva en länk direkt nedan: privat: Form1^ parentForm;

5) När vi klickar på knappen i Form2 anropar vi Set-metoden för det överordnade formuläret:

Privat: System::Void button1_Click(System::Object^ avsändare, System::EventArgs^ e) ( parentForm->Set("hej från form2"); parentForm->Show(); this->Hide(); )

6) Det återstår att öppna det andra formuläret i det första formuläret. För att göra detta flyttar vi knappklickshanteraren från Form1.h till Form1.cpp , och i .h-filen lämnar vi bara dess deklaration.

Ibland är det nödvändigt att komma åt elementen i ett formulär från ett annat under programexekveringen. Till exempel finns det ett formulär Form1, från det öppnar vi en annan Form2 och nu, när vi arbetar i Form2, måste vi komma åt elementen i det överordnade formuläret Form1. Jag hittade flera sätt att göra detta.

1:a metoden. Skicka en referens till en publik variabel.

Namnområde WindowsApplication1 ( offentlig delklass Form1: Form ( public Form1() ( InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( Form2 frm = new Form2(); frm.but1 = this.button1; // send länk till knappen i formuläret Form2 frm.ShowDialog(); ) ) )

I Form2 kommer variabeln som länken skickades till nu att motsvara knapp1 från Form1

Namnområde WindowsApplication1 ( offentlig delklass Form2: Form ( public Button but1; // denna variabel kommer att innehålla en länk till button1 från Form1 public Form2() ( InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( but1. Text = "test"; // ändra texten på knappen knapp1 i Form1 ) ) )

2:a metoden. Skickar länken till det underordnade formuläret.

Kärnan är ungefär densamma i den första metoden. När vi öppnar Form2 skickar vi in ​​en länk till det element som vi planerar att ändra senare.

Namnutrymme WindowsApplication1 ( offentlig delklass Form1: Form ( public Form1() ( InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( Form2 frm = new Form2(this.button1); // skicka en länk till knappen till formuläret Form2 frm.ShowDialog(); ) ) )

Nu i Form2 måste vi skapa en variabel som kommer att innehålla en länk till den här knappen och genom den kommer vi åt knappen på Form1 (raderna 5,7,9 och 15).

Namnutrymme WindowsApplication1 ( public partial class Form2: Form ( private Button but1; // denna variabel kommer att innehålla en länk till knappen button1 från formuläret Form1 public Form2(Button but) // få en länk till knappen i variabeln but ( but1 = men; // nu kommer but1 att vara en länk till knapp button1 InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( but1.Text = "test"; // ändra texten på knapp button1 i Form1 ) ) )

3:e metoden. Tillgång till hela föräldraformuläret.

För att göra detta måste du göra ändringar i flera filer, men samtidigt kommer vi att ha tillgång till alla element i det överordnade formuläret och behöver inte skicka en länk till varje element, som i metod 1.

Steg 1. I fil Program.cs skapa en publik variabel f1 (rad 5).

Namnområde WindowsApplication1 ( statisk klass Program ( offentlig statisk Form1 f1; // variabel som kommer att innehålla en länk till formuläret Form1 static void Main() ( Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1( ) ) ) ) )

Steg 2.Öppning Form1.Designer.cs och i den, för element som kommer att behöva nås från en annan form, ändrar vi privatoffentlig. Låt oss till exempel göra knapp1 på Form1 tillgänglig för ändringar.

Offentligt system.Windows.Forms.Button button1; // ersatt privat med offentlig

Steg 3. När vi skapar Form1 tilldelar vi variabel f1 en länk till detta formulär (rad 7)

Namnutrymme WindowsApplication1 ( offentlig delklass Form1: Form ( public Form1() ( Program.f1 = detta; // nu kommer f1 att vara en länk till formuläret Form1 InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( Form2 frm = new Form2(); frm.ShowDialog(); ) ) )

Steg 4. Nu från absolut vilken form som helst eller från vilken klass som helst kan du komma åt elementet button1 som finns på Form1 så här: Program.f1.button1. Låt till exempel knappen på Form2 ändra knapptexten på Form1:

Namnutrymme WindowsApplication1 ( offentlig delklass Form2: Form ( public Form2() ( InitializeComponent(); ) privat void button1_Click(objektavsändare, EventArgs e) ( Program.f1.button1.Text = "test"; // Ändra texten på formulärknapp Formulär1)))

Av admin.

Att lära sig C# går långsamt. men det fortsätter troget. Nyligen jag
gav ett exempel på hur man öppnar en annan från ett formulär i Visual C#. I princip är allt enkelt.

Idag dök följande uppgift upp: starta ett modalt formulär från applikationens huvudform; när det är stängt måste detta formulär skicka vissa data (text, egenskapsvärden, etc.) till kontrollerna i huvudformuläret. Det är inte möjligt att lösa detta problem med den metod som beskrivs i det tidigare inlägget om formulär, eftersom i det här fallet skapar vi helt enkelt ett nytt formulärobjekt med nya värden för alla egenskaper. Lyckligtvis har C# en underbar sophämtare... Men poängen är inte samlaren, utan hur man öppnar ett underordnat formulär i C# och sedan kommer tillbaka till huvudformuläret från det?

Till att börja med, låt oss ställa in de initiala (initiella) data.

Så. Vi har huvudansökningsformuläret:

Detta formulär innehåller också en textruta med namnet TBDialog och en knappknapp som vi ska klicka på:

  1. Godkänd värde Textegenskaper från TBDialog till TBMain;
  2. Stäng fDialog;

Låt oss nu titta på hela processen i ordning.

För det första är det alltid värt att komma ihåg att som standard är alla egenskaper, variabler och metoder i C# tilldelade en modifierare privat– därför, för att komma från den andra formen till kontrollen på den första, måste vi ställa in en modifierare för TBMain offentlig på egen hand. För att göra detta, välj TBMain-elementet i formulärdesignern, gå till egenskapsfönstret och ändra fastighetsvärdet Modifierare Med privatoffentlig

Nu kommer TBMain att synas i andra objekt. Låt oss gå vidare. För att öppna formuläret i modalt läge måste vi använda ett av två alternativ för metoden ShowDialog():

public DialogResult ShowDialog() ; public DialogResult ShowDialog(IWin32Window-ägare) ;

I det första fallet visar metoden formuläret som en modal dialogruta med det aktuella aktiva fönstret som ägare, och i det andra kan vi självständigt ange vilket formulär som kommer att bli ägare till vårt modala fönster.

Låt oss till exempel använda den andra versionen av metoden ShowDialog() och visa den andra formen modalt. För att göra detta kommer vi att skriva följande:

Här passade jag på igen nyckelord detta , som pekar på det aktuella objektet, dvs. ställ in huvudformuläret som ägare ( fMain). Låt oss nu gå direkt till att lösa vårt problem och svara på frågan: hur överför man värde från en form till en annan? Varje kontroll har en anmärkningsvärd egenskap Ägare – som pekar på föräldern:

Nu kan du köra projektet och se till att texten från TextBox på underformuläret överförs perfekt till TextBox på den första. För säkerhets skull lägger jag upp källkoden för projektet som diskuteras i exemplet.