Grafikus C# – Windows Forms tanfolyam › 6.7 lecke

Windows Forms · 6.7 lecke · alapértelmezett gombok

AcceptButton, CancelButton és alapértelmezett gombok

Minden Windows-felhasználó tudja: az Enter az „OK”, az Esc a „Mégse”. Ezt a viselkedést a programozónak nem kell megírnia: a Form két tulajdonsága, az AcceptButton és a CancelButton beállítja. Ebben a leckében megtanulod ezt a két tulajdonságot, a gombok DialogResult értékét, amely a párbeszédablakot magától bezárja, a bejelentkező ablak készítését, és azt is, mikor kell felülbírálnod az alapértelmezett viselkedést (több soros szövegmező, ellenőrzés a bezárás előtt, váltakozó alapértelmezett gomb).

  • kb. 100 perc
  • közepes szint
  • Enter és Esc
Diák C# programozást gyakorol egy tanulósarokban

A lecke végére

  • beállítod az AcceptButton és CancelButton tulajdonságot, és tudod, mikor érvényesülnek;
  • használod a gombok DialogResult tulajdonságát, és tudod, hogy a párbeszédablak ilyenkor magától bezárul;
  • a bezárást ellenőrzéshez kötöd (a DialogResult kódból, nem a gombon);
  • bejelentkező párbeszédablakot készítesz, és a főablak a ShowDialog eredménye alapján indul;
  • váltakozó alapértelmezett gombot állítasz be (Enter esemény), és a PerformClick metódust használod;
  • felismered a gyakori hibákat (többsoros mező, DialogResult ellenőrzés nélkül, CancelButton a főablakon).

Mielőtt elkezded

Ehhez a leckéhez az 5.4 lecke (Enter, ProcessCmdKey), a 6.6 lecke (fókusz, érvényesítés, CausesValidation), a 3.3 lecke (bejelentkezés) és az 1.2 lecke (MessageBox, DialogResult) szükséges. Új projektben próbáld ki a példákat.

6.6 Fókusz és navigáció →

AcceptButton és CancelButton

A Form két tulajdonsága egy-egy gombot jelöl ki:

TulajdonságBillentyűHatás
AcceptButtonEnterAz Enter lenyomása a kijelölt gomb Click eseményét váltja ki. Ez az alapértelmezett gomb: kicsit kiemelt keretet kap.
CancelButtonEscAz Esc lenyomása a kijelölt gomb Click eseményét váltja ki (általában a Mégse gomb).
Form1.csC#
// a tervezőben: Form → Properties → AcceptButton, CancelButton (legördülő lista a gombok nevével)
// kódból:
this.AcceptButton = btnOk;
this.CancelButton = btnMegse;

private void btnOk_Click(object sender, EventArgs e)
{
lblUzenet.Text = "OK megnyomva.";
}

private void btnMegse_Click(object sender, EventArgs e)
{
this.Close();
}
Csak az ablakon lévő gombA kijelölt gombnak ugyanazon az ablakon kell lennie. Ha egy panelen vagy lapon van, az is megfelel, ha látható és engedélyezett.
Letiltott gombHa az AcceptButton letiltott (Enabled = false) vagy láthatatlan, az Enter nem csinál semmit. Ezzel „kikapcsolható” az alapértelmezett művelet (például amíg a mezők üresek).
A fókuszban lévő gomb elsőbbséget élvezHa a felhasználó a Tab billentyűvel egy másik gombra lép, az Enter azt nyomja meg, és az lesz ideiglenesen az alapértelmezett (kiemelt keretet kap). Ez a Windows megszokott működése.
A szövegmezőkAz egysoros TextBox az Enter billentyűt átengedi az AcceptButtonnak. A többsoros mezőnél az AcceptsReturn tulajdonság dönt (lásd lent).

Jósolj!

Az AcceptButton a Mentés gomb. A felhasználó Tab billentyűvel a Törlés gombra lép, és megnyomja az Enter billentyűt. Melyik gomb fut le?

Jóslat ellenőrzése

A Törlés gomb: a fókuszban lévő gomb az Enter billentyűt megkapja, és saját magát nyomja meg. Az AcceptButton csak akkor lép működésbe, ha a fókusz olyan vezérlőn van, amely az Enter billentyűt nem használja (szövegmező, jelölőnégyzet, lista). Veszélyes funkciójú gombot (törlés) ezért ne tegyél az Enter hatókörébe, és a törlést erősítsd meg.

DialogResult: a párbeszédablak eredménye

A DialogResult egy felsorolás a párbeszédablak lehetséges eredményeivel: OK, Cancel, Yes, No, Abort, Retry, Ignore, None. A MessageBox.Show is ilyen értéket ad (1.2 lecke). Saját párbeszédablakoknál két helyen jelenik meg:

A gomb DialogResult tulajdonsága

Ha egy gomb DialogResult értékét beállítod (például OK), a gombra kattintás után a párbeszédablak magától bezárul, és a ShowDialog() ezt az értéket adja vissza. Kód nélkül.

A Form DialogResult tulajdonsága

Kódból is beállítható: this.DialogResult = DialogResult.OK;. Az érték beállítása bezárja az ablakot (modális esetben elrejti, és a ShowDialog visszatér). A DialogResult.None ezt megakadályozza.

BeallitasokForm.cs és Form1.csC#
// BeallitasokForm: a tervezőben
// btnOk.DialogResult = OK; AcceptButton = btnOk;
// btnMegse.DialogResult = Cancel; CancelButton = btnMegse;
// Kód nem kell a bezáráshoz.

// A hívó ablak (Form1):
private void btnBeallitasok_Click(object sender, EventArgs e)
{
using (BeallitasokForm ablak = new BeallitasokForm())
{
DialogResult eredmeny = ablak.ShowDialog(this);

if (eredmeny == DialogResult.OK)
{
lblUzenet.Text = "A beállítások elfogadva.";
}
else
{
lblUzenet.Text = "Mégsem.";
}
}
}
ShowDialog és usingA ShowDialog() modális ablakot nyit: a hívó kód addig vár, amíg az ablak be nem záródik. A using blokk az ablakot (a modális ablakot a bezárás nem szabadítja fel) a végén felszabadítja (3.9 lecke).
Az Esc és a CancelA CancelButton gombja DialogResult.Cancel értékkel zárja be az ablakot, ha a gombnak ez az értéke van beállítva. A bezáró X gomb DialogResult.Cancel eredményt ad.
Más ablakok eredményeAz Yes, No értékek eldöntendő kérdéseknél használhatók (MessageBox, saját kérdés ablak).
Adatok átvételeAz ablak által gyűjtött adatot a hívó az ablak nyilvános tulajdonságain át veszi át (például ablak.Nev), a using blokkon belül, a felszabadítás előtt. Részletesen a 7.7 leckében.

Jósolj!

Egy párbeszédablak OK gombjának DialogResult értéke OK, és a Click kezelőjében MessageBox.Show("Mentve") áll. Mi történik a gomb megnyomásakor?

Jóslat ellenőrzése

Először lefut a Click kezelő (megjelenik az üzenet), majd az ablak a kezelő lefutása után bezárul az OK eredménnyel. A bezárás tehát mindig a kezelő után történik.

Ellenőrzés a bezárás előtt

A gomb DialogResult értéke ellenőrzés nélkül zár

Ha az OK gomb DialogResult tulajdonsága OK, a párbeszédablak akkor is bezárul, ha az adatok hibásak: a Click kezelő lefut, és közvetlenül utána zár. Ha az adatokat ellenőrizni kell, a gomb DialogResult értéke maradjon None, és a bezárást a kód végezze, csak sikeres ellenőrzés után: this.DialogResult = DialogResult.OK;.

BejelentkezesForm.cs (btnOk.DialogResult = None; AcceptButton = btnOk; btnMegse.DialogResult = Cancel; CancelButton = btnMegse)C#
private int probalkozas = 0;

public string Felhasznalo { get; private set; } = "";

private void btnOk_Click(object sender, EventArgs e)
{
string nev = txtFelh.Text.Trim();

if (nev.Length == 0 || txtJelszo.Text.Length == 0)
{
lblHiba.Text = "Töltsd ki mindkét mezőt!";
txtFelh.Focus();
return; // az ablak nyitva marad
}

probalkozas = probalkozas + 1;

if (nev == "diak" && txtJelszo.Text == "jelszo123") // DEMÓ: valódi programban adatbázis és hash (3.3 lecke)
{
Felhasznalo = nev;
this.DialogResult = DialogResult.OK; // csak siker esetén zárunk
}
else if (probalkozas >= 3)
{
this.DialogResult = DialogResult.Abort; // három hibás kísérlet után feladjuk
}
else
{
lblHiba.Text = $"Hibás adatok ({probalkozas}/3).";
txtJelszo.Clear();
txtJelszo.Focus();
}
}
DialogResult kódbólA this.DialogResult = ... sor bezárja az ablakot. Csak a sikeres ágban állítsd be.
AbortA három hibás kísérlet után az ablak Abort eredménnyel zárul, a hívó kód ezt külön kezelheti (például kilép). A Cancel a felhasználó szándékos megszakítása, az Abort a program döntése.
A Mégse és az ellenőrzésA Mégse gomb CausesValidation értéke legyen hamis (6.6 lecke), hogy hibás mező mellett is megnyomható legyen.
Nincs titkos adat a kódbanA fenti felhasználónév és jelszó csak a bemutatás miatt van a kódban. Valódi programban a jelszót soha nem tárolod nyílt szövegként: az adatbázisban hash-elve (3.3 lecke, 13. fejezet).

Jósolj!

A Bejelentkezés gomb DialogResult tulajdonsága az OK értékre van állítva a tervezőben, és a Click kezelő hibás adatnál csak egy üzenetet ír ki (return-nel kilép). Zárul-e az ablak hibás jelszónál?

Jóslat ellenőrzése

Igen, bezárul, és a ShowDialog OK eredményt ad, tehát a program a bejelentkezést sikeresnek veszi! A gomb tulajdonsága a kezelő futása után mindenképp zár. Ez komoly biztonsági hiba is lehet. A javítás: a gomb DialogResult értéke None, és a kód this.DialogResult = DialogResult.OK; sort csak sikeres ellenőrzésnél hajtja végre. (A kezelőben a this.DialogResult = DialogResult.None; sor is megakadályozhatja a zárást, de az első megoldás átláthatóbb.)

Váltakozó alapértelmezett gomb és a PerformClick

Több mező, több alapértelmezett művelet

Egy ablakon gyakran két külön „ügy” van: egy kereső (Enter = Keresés) és egy szerkesztő (Enter = Mentés). Az AcceptButton értéke futás közben is átállítható, ezért az Enter esemény (a fókuszba kerülés) átkapcsolja:

Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
txtKereso.Enter += (s, ev) => Alapertelmezett(btnKeres);
txtNev.Enter += (s, ev) => Alapertelmezett(btnMent);
txtJegyzet.Enter += (s, ev) => Alapertelmezett(null); // többsoros: az Enter új sort ad
}

private void Alapertelmezett(Button gomb)
{
this.AcceptButton = gomb;
lblSugo.Text = gomb == null ? "Az Enter új sort kezd." : "Az Enter most: " + gomb.Text;
}

PerformClick: a gomb megnyomása kódból

A Button.PerformClick() úgy nyomja meg a gombot, mintha a felhasználó kattintott volna: lefut a Click eseménye (ha a gomb engedélyezett és látható). Így egy gyorsbillentyű vagy egy másik esemény ugyanazt a kódot használja, nem kell megismételni:

Form1.csC#
// Ctrl+Enter a többsoros mezőben elküldi az üzenetet (az Enter új sort ad)
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Enter) && txtUzenet.Focused)
{
btnKuld.PerformClick();
return true;
}

return base.ProcessCmdKey(ref msg, keyData);
}
AcceptsReturnA többsoros TextBox (Multiline = true) AcceptsReturn tulajdonsága határozza meg az Enter sorsát: true esetén új sort ad a szövegbe (az AcceptButton nem kapja meg), false esetén az AcceptButton kapja. Szerkesztőmezőben állítsd igazra.
RichTextBoxA RichTextBox többsoros, és az Enter új sort ad, az AcceptButton nem kapja meg.
AcceptButton = nullA null érték megszünteti az alapértelmezett gombot, ilyenkor az Enter nem aktivál gombot.
PerformClick és letiltott gombLetiltott vagy rejtett gombra a PerformClick hatástalan. Ez hasznos: a gomb állapota egy helyen szabályozza a műveletet, és a gyorsbillentyű ugyanúgy követi.

Jósolj!

Egy többsoros TextBox (Multiline = true, AcceptsReturn = false) mellett az ablak AcceptButton értéke a Küldés gomb. A felhasználó a mezőben megnyomja az Enter billentyűt. Mi történik?

Jóslat ellenőrzése

Az Enter a Küldés gombot nyomja meg, nem ad új sort: a felhasználó a levelet félig megírva elküldi! Új sorhoz Ctrl+Enter kell. Szerkesztésre szánt többsoros mezőnél állítsd az AcceptsReturn értékét true-ra, és az elküldéshez használj külön gombot vagy Ctrl+Enter billentyűt.

📷 Képernyőkép helye

Mit tegyél ide: a bejelentkező párbeszédablak a kiemelt Bejelentkezés gombbal (alapértelmezett keret), és alatta a „Hibás adatok (2/3).” üzenet.Javasolt fájlnév: winforms-6-7-login.webp · Alt szöveg: A bejelentkező ablak alapértelmezett gombbal

Hibakeresés: te vagy a hibadetektív

Mi a baj, és hogyan javítod?

Gondold végig az okot, és csak utána nyisd le a megoldást.

1. Az Enter elküldi a félkész szöveget

Egy többsoros mezőben az Enter megnyomja a Küldés gombot.

Ok és javítás

A mező AcceptsReturn értéke hamis, ezért az Enter az AcceptButtonra megy. Állítsd az AcceptsReturn értékét true-ra (vagy használj RichTextBox-ot), és a küldéshez külön gomb vagy Ctrl+Enter kell.

2. A bejelentkezés hibás jelszóval is sikerül

// btnOk.DialogResult = OK a tervezőben
private void btnOk_Click(object sender, EventArgs e)
{
if (txtJelszo.Text != "titok")
{
lblHiba.Text = "Hibás jelszó";
}
}
Hiba és javítás

A gomb DialogResult tulajdonsága zár, a kezelő eredményétől függetlenül, és az OK eredménnyel tér vissza a ShowDialog. Hagyd a gomb tulajdonságát None-on, és a sikeres ágban állítsd be: this.DialogResult = DialogResult.OK;.

3. Az Esc kilép a főablakból

A főablakban véletlenül az Esc billentyűre bezárul az egész program.

Ok és javítás

A főablak CancelButton értéke egy kilépő gomb. A CancelButton a párbeszédablakoknak való: főablaknál töröld (null), vagy az Esc kezelés kérdezzen rá a kilépésre (FormClosing).

4. Az Enter semmit sem csinál

Az AcceptButton be van állítva, de az Enter nem hat.

Ok és javítás

Az alapértelmezett gomb valószínűleg letiltott vagy rejtett, vagy a fókusz egy olyan vezérlőn van, amely az Enter billentyűt használja (többsoros mező AcceptsReturn értékkel, a lista egyes módjai). Ellenőrizd a gomb Enabled és Visible értékét.

5. A Mégse hibás mező mellett nem működik

A felhasználó nem tud kilépni a párbeszédablakból, ha egy mező hibás.

Ok és javítás

A Validating esemény megakadályozza a fókuszváltást, és a Mégse gomb CausesValidation értéke igaz. Állítsd hamisra (6.6 lecke).

6. A dialógus kétszer jelenik meg vagy nem tér vissza

BeallitasokForm ablak = new BeallitasokForm();
ablak.Show(); // nem modális: a kód nem várja meg az eredményt
if (ablak.DialogResult == DialogResult.OK) { } // ekkor még None
Hiba és javítás

A Show() azonnal visszatér, ezért az eredmény még nem ismert. Az eredményt a ShowDialog() adja vissza, amely megvárja az ablak bezárását. Használd a ShowDialog() metódust, ha az eredmény kell.

Mini projekt: bejelentkező ablak és váltakozó alapértelmezett gomb

Készíts programot két részből:

  1. Bejelentkező ablak (BejelentkezesForm): txtFelh, txtJelszo (UseSystemPasswordChar), chkMutat (a jelszó megjelenítése), lblHiba, Bejelentkezés (btnOk, AcceptButton, DialogResult = None) és Mégse (btnMegse, CancelButton, DialogResult = Cancel, CausesValidation = false). Az ellenőrzés: mindkét mező kitöltött; a demó adatok: diak és jelszo123; három hibás kísérlet után Abort.
  2. A program indítása (Program.cs): a bejelentkező ablak ShowDialog() hívással nyílik; csak OK eredménynél indul a főablak (Application.Run), a felhasználónévvel a címsorban; Cancel és Abort esetén a program kilép.
  3. Főablak (Form1): egy Keresés csoport (txtKereso, btnKeres), egy Jegyzet csoport (txtNev, txtJegyzet többsoros, AcceptsReturn, btnMent), és egy lblSugo címke. Az AcceptButton váltakozik a fókusz szerint: a txtKereso mezőben Keresés, a txtNev mezőben Mentés, a txtJegyzet mezőben nincs (új sor); a lblSugo mutatja, mit tesz az Enter.
  4. A Ctrl+Enter a jegyzet mezőben a Mentés gombot nyomja meg (PerformClick).
  5. A főablak CancelButton értéke nincs; az Esc a keresőmezőt üríti.
  6. Teszteld: bejelentkezés jó és rossz adatokkal (3 kísérlet), Mégse, Esc, Enter a három mezőben, Ctrl+Enter, a jelszó mutatása.
Megoldás megnyitása (próbáld ki előbb önállóan!)

A Form1 konstruktora a felhasználónevet kapja paraméterként (a 12. fejezet ezt részletesen tárgyalja): public Form1(string felhasznalo). Az InitializeComponent hívás után állítjuk be a címsort. A Program.cs a dialógus using blokkjában olvassa ki a felhasználónevet.

Program.cs, BejelentkezesForm.cs, Form1.csC#
// Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

string felhasznalo;

using (BejelentkezesForm login = new BejelentkezesForm())
{
if (login.ShowDialog() != DialogResult.OK)
{
return; // Mégse vagy Abort: a program kilép
}

felhasznalo = login.Felhasznalo;
}

Application.Run(new Form1(felhasznalo));
}

// BejelentkezesForm.cs
private int probalkozas = 0;

public string Felhasznalo { get; private set; } = "";

private void chkMutat_CheckedChanged(object sender, EventArgs e)
{
txtJelszo.UseSystemPasswordChar = !chkMutat.Checked;
}

private void btnOk_Click(object sender, EventArgs e)
{
string nev = txtFelh.Text.Trim();

if (nev.Length == 0 || txtJelszo.Text.Length == 0)
{
lblHiba.Text = "Töltsd ki mindkét mezőt!";
txtFelh.Focus();
return;
}

probalkozas = probalkozas + 1;

if (nev == "diak" && txtJelszo.Text == "jelszo123")
{
Felhasznalo = nev;
this.DialogResult = DialogResult.OK;
}
else if (probalkozas >= 3)
{
this.DialogResult = DialogResult.Abort;
}
else
{
lblHiba.Text = $"Hibás adatok ({probalkozas}/3).";
txtJelszo.Clear();
txtJelszo.Focus();
}
}

// Form1.cs
public Form1(string felhasznalo)
{
InitializeComponent();
this.Text = "Jegyzetek – " + felhasznalo;
}

private void Form1_Load(object sender, EventArgs e)
{
this.AcceptButton = null;

txtKereso.Enter += (s, ev) => Alapertelmezett(btnKeres);
txtNev.Enter += (s, ev) => Alapertelmezett(btnMent);
txtJegyzet.Enter += (s, ev) => Alapertelmezett(null);
txtJegyzet.AcceptsReturn = true;
}

private void Alapertelmezett(Button gomb)
{
this.AcceptButton = gomb;
lblSugo.Text = gomb == null ? "Az Enter új sort kezd." : "Az Enter most: " + gomb.Text;
}

private void btnKeres_Click(object sender, EventArgs e)
{
lblEredmeny.Text = "Keresés: " + txtKereso.Text.Trim();
}

private void btnMent_Click(object sender, EventArgs e)
{
lblEredmeny.Text = $"Mentve: {txtNev.Text.Trim()} ({txtJegyzet.TextLength} karakter)";
}

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Enter) && txtJegyzet.Focused)
{
btnMent.PerformClick();
return true;
}

if (keyData == Keys.Escape && txtKereso.Focused)
{
txtKereso.Clear();
return true;
}

return base.ProcessCmdKey(ref msg, keyData);
}
📷 Képernyőkép helye

Mit tegyél ide: a főablak a „Az Enter most: Mentés” súgósorral és a kitöltött jegyzettel.Javasolt fájlnév: winforms-6-7-kesz.webp · Alt szöveg: A váltakozó alapértelmezett gombot használó ablak

Három önálló gyakorlófeladat

Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.

1. Beviteli ablak (InputBox)

Készíts KerdesForm párbeszédablakot, amely egy kérdést (lblKerdes) és egy beviteli mezőt (txtValasz) mutat, OK és Mégse gombbal. A hívó így használja: string nev = KerdesForm.Kerdez("Mi a neved?"); (null a Mégse esetén). Hogyan oldod meg?

Egy lehetséges megoldás

Egy statikus segédmetódus a using blokkban megnyitja az ablakot, és az eredményt visszaadja. Az OK gomb DialogResult tulajdonsága OK (az üres válasz is elfogadott), a Mégse Cancel.

KerdesForm.csC#
public static string Kerdez(string kerdes)
{
using (KerdesForm ablak = new KerdesForm())
{
ablak.lblKerdes.Text = kerdes;

if (ablak.ShowDialog() == DialogResult.OK)
{
return ablak.txtValasz.Text;
}

return null;
}
}

// használat:
string nev = KerdesForm.Kerdez("Mi a neved?");

if (nev != null)
{
lblUdv.Text = "Szia, " + nev + "!";
}

2. Mentetlen változtatás az Esc billentyűnél

Egy szerkesztő párbeszédablakban az Esc (Mégse) csak akkor zárjon azonnal, ha nincs módosítás. Módosításnál kérdezzen rá. Hol kezeled?

Egy lehetséges megoldás

A FormClosing eseményben: az Esc és a bezáró X is ide vezet. A felhasználói bezárásnál (UserClosing) kérdez, ha a modosult jelző igaz és az eredmény nem OK.

SzerkesztoForm.csC#
private bool modosult = false;

private void txtAdat_TextChanged(object sender, EventArgs e)
{
modosult = true;
}

private void SzerkesztoForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult == DialogResult.OK || !modosult || e.CloseReason != CloseReason.UserClosing)
{
return;
}

if (MessageBox.Show("Elveted a változtatásokat?", "Mégse", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}

3. Váltakozó gomb füles felületen

Egy TabControl Keresés lapján az Enter a Keresés, a Szerkesztés lapon a Mentés gombot nyomja meg. Melyik eseménnyel állítod az AcceptButton értékét?

Egy lehetséges megoldás

A SelectedIndexChanged eseményben, a kiválasztott lap szerint. Az induláskor is be kell állítani (a Load eseményben).

Form1.csC#
private void AlapGomb()
{
if (tc.SelectedTab == tabKereses)
{
this.AcceptButton = btnKeres;
}
else if (tc.SelectedTab == tabSzerkesztes)
{
this.AcceptButton = btnMent;
}
else
{
this.AcceptButton = null;
}
}

private void tc_SelectedIndexChanged(object sender, EventArgs e)
{
AlapGomb();
}

private void Form1_Load(object sender, EventArgs e)
{
AlapGomb();
}

Gyakorlótár: 6 további feladat

Három szinten gyakorolhatsz: alap, közepes és kihívás. Csak a próbálkozás után nyisd le a megoldást.

Alap szint

1. DialogResult értékek

Add meg, melyik DialogResult értéket adná (a) az OK gomb, (b) az Igen gomb, (c) a bezáró X gomb, (d) az ablak, ha a program három hibás próbálkozás után feladja.

Megoldás megnyitása

(a) OK; (b) Yes; (c) Cancel; (d) Abort (a program döntése).

2. Gombok beállítása kódból

Állítsd be kódból egy párbeszédablak Mentés gombját alapértelmezettnek, a Mégse gombot megszakítónak, és a gombok DialogResult értékét.

Megoldás megnyitása

Az AcceptButton és CancelButton az ablak tulajdonságai, a DialogResult a gombok tulajdonsága.

Form.csC#
this.AcceptButton = btnMent;
this.CancelButton = btnMegse;

btnMent.DialogResult = DialogResult.OK;
btnMegse.DialogResult = DialogResult.Cancel;

Közepes szint

3. Igen–Nem–Mégse

Mentetlen dokumentum bezárásakor a MessageBox három gombbal kérdez (Igen: mentés, Nem: elvet, Mégse: marad). Írd meg a feldolgozást switch utasítással.

Megoldás megnyitása

A MessageBox.Show DialogResult értéket ad, amelyre a switch (5.8 lecke) jól illik.

Form1.csC#
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (!modosult || e.CloseReason != CloseReason.UserClosing)
{
return;
}

switch (MessageBox.Show("Mented a változtatásokat?", "Kilépés", MessageBoxButtons.YesNoCancel))
{
case DialogResult.Yes:
if (!Ment())
{
e.Cancel = true;
}
break;

case DialogResult.No:
break; // elvetjük

default:
e.Cancel = true; // Mégse
break;
}
}

4. Az OK gomb csak kitöltéskor aktív

Az OK gomb legyen letiltott, amíg a név és az e-mail mező nem üres. Mi történik ilyenkor az Enter billentyűvel?

Megoldás megnyitása

A letiltott AcceptButton miatt az Enter nem csinál semmit (a gomb nem aktív). A TextChanged események frissítik az Enabled értéket (5.5 lecke). Ez egyszerű, érthető védelem, de a felhasználó nem tudja, miért nem reagál: egy rövid súgószöveg segít.

Form.csC#
private void Frissit()
{
bool kesz = txtNev.Text.Trim().Length > 0 && txtEmail.Text.Trim().Length > 0;

btnOk.Enabled = kesz;
lblSugo.Text = kesz ? "" : "Töltsd ki a nevet és az e-mail címet.";
}

private void Mezo_TextChanged(object sender, EventArgs e)
{
Frissit();
}

Kihívás szint

5. Alkalmaz gomb a párbeszédablakban

Egy beállító párbeszédablakban az Alkalmaz gomb elmenti a beállításokat, de az ablakot nem zárja be. Az OK alkalmaz és zár, a Mégse csak zár. Hogyan oldod meg úgy, hogy az OK és az Alkalmaz ugyanazt a kódot használja?

Megoldás megnyitása

Közös Alkalmaz() metódus, amelyet mindkét gomb hív. Az Alkalmaz gomb DialogResult értéke None, az OK gombé szintén (hogy az ellenőrzés után zárjon a kód).

BeallitasokForm.csC#
private bool Alkalmaz()
{
if (txtPort.Text.Length == 0)
{
lblHiba.Text = "Add meg a portot!";
return false;
}

// a beállítások mentése
btnAlkalmaz.Enabled = false;
return true;
}

private void btnAlkalmaz_Click(object sender, EventArgs e)
{
Alkalmaz();
}

private void btnOk_Click(object sender, EventArgs e)
{
if (Alkalmaz())
{
this.DialogResult = DialogResult.OK;
}
}

6. Enter a listában

Egy ListBox elemén az Enter az elem megnyitását jelentse (ugyanazt, mint a dupla kattintás), a többi helyen az AcceptButton működjön. Mit kell tenned, hogy az Enter ne az alapértelmezett gombot indítsa a listából?

Megoldás megnyitása

Az Enter esemény átállítja az AcceptButton értékét null-ra a lista fókuszánál, és a KeyDown esemény kezeli az Enter billentyűt; a Leave esemény visszaállítja az alapértelmezett gombot.

Form1.csC#
private void lstElemek_Enter(object sender, EventArgs e)
{
this.AcceptButton = null;
}

private void lstElemek_Leave(object sender, EventArgs e)
{
this.AcceptButton = btnOk;
}

private void lstElemek_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter && lstElemek.SelectedItem != null)
{
e.SuppressKeyPress = true;
MessageBox.Show("Megnyitás: " + lstElemek.SelectedItem);
}
}

Gyors önellenőrzés

Válaszolj fejben, és csak utána nyisd le a választ.

1. Mit csinál az AcceptButton és a CancelButton?

Az Enter az AcceptButton, az Esc a CancelButton Click eseményét váltja ki.

2. Mit tesz a gomb DialogResult tulajdonsága?

A gombra kattintás után a párbeszédablak a kezelő lefutása után magától bezárul, és a ShowDialog ezt az értéket adja vissza.

3. Miért kell ellenőrzésnél None a gomb DialogResult értéke?

Mert a gomb értéke ellenőrzés nélkül zár. Az ellenőrzés után a kód állítja be: this.DialogResult = DialogResult.OK;.

4. Mi a különbség a Show és a ShowDialog között?

A Show() azonnal visszatér (nem modális), a ShowDialog() megvárja az ablak bezárását, és eredményt ad.

5. Mi az AcceptsReturn szerepe?

A többsoros szövegmezőben igaz értéknél az Enter új sort ad, hamis értéknél az AcceptButtont aktiválja.

6. Mire való a PerformClick?

Kódból megnyomja a gombot: lefut a Click kezelője (ha a gomb engedélyezett és látható), így nem kell a kódot megismételni.

7. Mikor ne legyen CancelButton a főablakon?

Mindig, ha az Esc a programot zárná be. A CancelButton a párbeszédablakoknak való.

Mit tudsz már?

  • Beállítod az AcceptButton és CancelButton értékét, és érted a működésüket.
  • A gombok DialogResult tulajdonságával párbeszédablakot zársz, és az ellenőrzést helyesen kezeled.
  • Bejelentkező ablakot készítesz, és a ShowDialog eredménye szerint indítod a programot.
  • Váltakozó alapértelmezett gombot állítasz be, és használod a PerformClick metódust.
  • Felismered a gyakori hibákat (AcceptsReturn, ellenőrzés nélküli DialogResult).

Következő lecke: Méretezhetőség, DPI és betűméret

Az űrlap a különböző képernyőkön és betűméreteknél: automatikus skálázás, DPI és a rögzített méretek veszélyei.