Grafikus C# – Windows Forms tanfolyam › 6.1 lecke Windows Forms · 6.1 lecke · az ablak tulajdonságai Az ablak a program arca: a felhasználó először a méretét, a címét és az ikonját látja. Ebben a leckében a Form mérete, helye, címe és ikonja
Form legfontosabb megjelenési tulajdonságait ismered meg: hogyan állítsd be a méretet (Size és ClientSize), a helyet (Location, StartPosition), a keretet és a gombokat (FormBorderStyle, ControlBox), a címet (Text) és az ikont (Icon). Megtanulod azt is, hogyan igazítsd az ablakot a képernyőhöz, és hogyan kerüld el a leggyakoribb csapdákat.
A lecke végére
- megkülönbözteted a
Sizeés aClientSizetulajdonságot, és tudod, melyiket mikor használd; - beállítod az ablak helyét (
StartPosition,Location), és igazítod a képernyő munkaterületéhez; - korlátozod az ablak méretét (
MinimumSize,MaximumSize), és kiválasztod a megfelelő keretstílust (FormBorderStyle); - kezeled a címsor gombjait és megjelenését (
ControlBox,MinimizeBox,MaximizeBox,ShowInTaskbar); - dinamikus címet írsz, és ikont állítasz be (a tervezőben és kódból);
- kezeled az ablak állapotát (
WindowState) és a méretváltozás eseményeit (Resize,ResizeEnd).
Mielőtt elkezded
Ehhez a leckéhez az 0.5–0.7 lecke (Form1.Designer.cs, Properties ablak), az 5.5 lecke (változás-események, jelző) és az 5.6 lecke (RestoreBounds, Screen) szükséges. Új Windows Forms projektben próbáld ki a példákat.
Az ablak mérete: Size és ClientSize
Az ablaknak két mérete van, és a kettő nem azonos:
Size
Az ablak teljes mérete: a keret, a címsor és a tartalom együtt. Ez az, amit a képernyőn látsz, és a tervezőben az ablak szélein húzással állítasz.
ClientSize
Az ablak belső, használható területe (kliensterület): a vezérlők ide kerülnek. A keret és a címsor nélküli méret, ezért mindig kisebb a Size értéknél.
private void Form1_Load(object sender, EventArgs e)
{
lblInfo.Text = $"Size: {this.Size.Width} x {this.Size.Height}\u000a"
+ $"ClientSize: {this.ClientSize.Width} x {this.ClientSize.Height}";
}
// méret beállítása:
this.Size = new Size(800, 600); // a teljes ablak 800 x 600
this.ClientSize = new Size(800, 600); // a használható terület 800 x 600 (az ablak nagyobb)
this.Width = 800; // csak a szélesség
this.Height = 600; // csak a magasságClientSize a jó. Ha a képernyőhöz viszonyítva igazítasz (a jobb alsó sarokba), a Size kell.ClientSize értéket.Size egy struct (Width, Height). Nem módosítható közvetlenül (this.Size.Width = 5 hiba), mindig új értéket kell adni, vagy a this.Width tulajdonságot használni.(0, 0) érték azt jelenti: nincs korlát.Jósolj!
A Form1_Load eseményben ezt írod: this.ClientSize = new Size(400, 300);. Mekkora lesz a this.Size: nagyobb, kisebb vagy ugyanennyi, mint a 400 × 300?
Jóslat ellenőrzése
Nagyobb: a Size tartalmazza a keretet és a címsort is, így a szélessége kb. 16, a magassága kb. 39 képponttal nagyobb (például 416 × 339), ha az ablak normál, méretezhető kerettel rendelkezik. A pontos érték a Windows verziójától és a megjelenítési beállításoktól függ. A tanulság: a tartalom méretéhez a ClientSize a megbízható.
Az ablak helye: StartPosition és Location
Az ablak induló helyét a StartPosition tulajdonság határozza meg:
| Érték | Jelentése |
|---|---|
WindowsDefaultLocation | Az alapértelmezés: a Windows választ helyet (általában kissé eltolva az előző ablakhoz képest). |
CenterScreen | A képernyő közepén. |
CenterParent | A gazdaablak (owner) közepén. Párbeszédablakoknál ez a jó (7. fejezet). |
Manual | Pontosan a Location tulajdonság szerint. |
WindowsDefaultBounds | A Windows választ helyet és méretet is. |
// 1. a képernyő közepére
this.StartPosition = FormStartPosition.CenterScreen;
// 2. pontos helyre: Manual kell, különben a Location nem számít
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(100, 50);
// 3. futás közben középre (a megjelenés után is működik)
this.CenterToScreen();
// 4. a jobb alsó sarokba, a tálca felett (értesítő ablak)
Rectangle munka = Screen.PrimaryScreen.WorkingArea;
this.Location = new Point(munka.Right - this.Width - 10, munka.Bottom - this.Height - 10);Screen.PrimaryScreen.Bounds a teljes képernyő. Az ablak igazításánál a munkaterület a jó, így nem lóg a tálca alá.StartPosition csak indulásnál számít).Screen.AllScreens a monitorok tömbje, a Screen.FromControl(this) azt a monitort adja, amelyen az ablak van (5.6 lecke).Jósolj!
A tervezőben a Location értéke (300, 200), de a StartPosition az alapértelmezett WindowsDefaultLocation. Hol jelenik meg az ablak?
Jóslat ellenőrzése
A Windows által választott helyen, nem a (300, 200) pontnál: a Location csak StartPosition = Manual esetén érvényesül. Ez az egyik leggyakoribb „miért nem működik a Location?” hiba.
Keretstílus és a címsor gombjai
Az ablak megjelenését és méretezhetőségét a FormBorderStyle tulajdonság szabályozza:
| Érték | Megjelenés | Mikor használd? |
|---|---|---|
Sizable | Alapértelmezett: méretezhető keret. | Főablak, szerkesztő. |
FixedSingle | Vékony, nem méretezhető keret. | Fix elrendezésű program (játék, kalkulátor). |
Fixed3D | Domború, nem méretezhető keret. | Régi stílusú ablak. |
FixedDialog | Párbeszédablak: nem méretezhető, nincs ikon a címsorban. | Beállítás, About, adatbekérő ablak. |
FixedToolWindow, SizableToolWindow | Vékony címsor, nincs tálcagomb (a ShowInTaskbar hamis). | Eszköztár, kis segédablak. |
None | Nincs keret és címsor. | Indítóképernyő (splash), saját kinézetű ablak (de nincs mozgatás és bezárás magától). |
A címsor gombjait ezek a tulajdonságok adják: a ControlBox (a címsor gombjai és a rendszermenü), a MinimizeBox, a MaximizeBox, valamint a ShowIcon (az ikon a címsorban) és a ShowInTaskbar (a tálcán):
// egy rögzített méretű játékablak
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false; // nem nagyítható
this.StartPosition = FormStartPosition.CenterScreen;
// egy segédablak: nincs tálcagomb, mindig felül
segedAblak.ShowInTaskbar = false;
segedAblak.TopMost = true;
// méretkorlát egy szerkesztő ablaknál
this.MinimumSize = new Size(640, 420); // ennél kisebbre nem húzhatóFixedSingle ablak kézzel nem méretezhető, de ha a MaximizeBox igaz marad, a nagyítógomb megmarad, és az ablak teljes képernyősre nőhet úgy, hogy a vezérlői nem követik. Ezért fix elrendezésű ablaknál kapcsold ki a nagyítógombot.Tilos zsákutcát építeni
Ha egy ablaknak ControlBox = false és nincs benne bezáró gomb, vagy a FormBorderStyle = None ablakot nem lehet mozgatni és bezárni, a felhasználó csak a Feladatkezelőből tud kilépni. Mielőtt eltávolítod a beépített gombokat, gondoskodj a helyettesítésükről (kilépés gomb, Esc billentyű, mozgatás a 5.3 lecke Gyakorlótárának mintájára).
Jósolj!
A FormBorderStyle értéke FixedDialog, a MinimizeBox és MaximizeBox is igaz. Mit látsz a címsorban?
Jóslat ellenőrzése
A FixedDialog stílusnál az ablaknak általában nincs kicsinyítő és nagyító gombja, csak a bezáró gomb, akkor is, ha a MinimizeBox és a MaximizeBox igaz. A párbeszédablak természete ez. Ha mégis szükséged van a kicsinyítésre, a Sizable vagy a FixedSingle stílust használd. (A viselkedést a saját Windowsodon érdemes kipróbálni, a megjelenés a verziótól függhet.)
Az ablak címe és ikonja
Cím: a Text tulajdonság
A címsor szövegét a Text tulajdonság adja. Nemcsak fix szöveg lehet: a program állapotát is mutathatja (nyitott fájl, módosítás jelzés):
private string fajlNev = "";
private bool modosult = false;
private void CimFrissit()
{
string nev = fajlNev.Length == 0 ? "Névtelen" : System.IO.Path.GetFileName(fajlNev);
string csillag = modosult ? "*" : "";
this.Text = nev + csillag + " – MiniWord"; // például: jegyzet.rtf* – MiniWord
}A cím szokás szerint a dokumentum neve – a program neve alakú, a módosítást csillag (*) jelzi (2.14 lecke). A cím a tálcán és az Alt+Tab váltóban is látszik, ezért legyen rövid és beszédes.
Ikon: az Icon tulajdonság
Az ablak ikonja a címsor bal oldalán és a tálcán jelenik meg. Beállítása:
- Készíts vagy tölts le egy
.icofájlt (az ikon több méretet is tartalmazhat: 16, 32, 48, 256 képpont). PNG képből online átalakítók vagy képszerkesztők készítenek ikont. - A tervezőben jelöld ki az ablakot, a Properties ablakban az
Iconsorban kattints a … gombra, és válaszd ki az.icofájlt. A Visual Studio az ikont aForm1.resxfájlba ágyazza (a futtatható fájlba kerül, külön fájl nem kell). - A program EXE fájljának ikonját (a Fájlkezelőben látszik) a projekt tulajdonságainál állítod: Project → Properties → Application → Icon. Ez más beállítás, mint az ablak ikonja!
// ikon betöltése fájlból (a fájlnak a program mellett kell lennie)
this.Icon = new Icon("ikon.ico");
// ikon az erőforrások közül (Properties → Resources → hozzáadott .ico): nem kell külön fájl
this.Icon = Properties.Resources.ikonPiros;
// az ikon elrejtése a címsorban
this.ShowIcon = false;new Icon("ikon.ico") a futtatás helyétől függő útvonalat használ: másik gépen vagy mappából indítva hibát (FileNotFoundException) adhat. Az erőforrásba ágyazott ikon a programmal együtt utazik, ezért megbízhatóbb.FormBorderStyle = FixedDialog ablakoknál amúgy sincs ikon a címsorban.Icon tulajdonság átállítható (például értesítésnél piros ikonra): a tálca is frissül.NotifyIcon komponens az értesítési területre (a tálca órájának környékére) tesz ikont, ez külön eszköz.Jósolj!
Beállítod az ablak Icon tulajdonságát egy saját ikonra, de a projekt Application → Icon beállítását nem változtatod. Milyen ikont látsz (a) a címsorban, (b) a tálcán, (c) a Fájlkezelőben az EXE fájlnál?
Jóslat ellenőrzése
(a) és (b): a saját ikonod (az ablak ikonja). (c): az alapértelmezett ikon (a projekt alkalmazásikonja), mert az EXE fájl ikonját a projekt tulajdonságai adják, nem az ablaké. Egy kész programnál mindkettőt érdemes ugyanarra az ikonra állítani.
Ablakállapot és a méretváltozás eseményei
A WindowState tulajdonság az ablak állapotát adja: Normal, Minimized (kicsinyített) vagy Maximized (maximalizált). Kódból is beállítható (this.WindowState = FormWindowState.Maximized;), és az ablak méretváltozásakor több esemény fut:
| Esemény | Mikor fut? | Használat |
|---|---|---|
Resize | Az ablak mérete változik (húzás közben folyamatosan, sokszor). | Gyors, egyszerű frissítés (felirat). |
SizeChanged | A Size megváltozott (a Resize párja). | Hasonló a Resize-hoz. |
ResizeEnd | A felhasználó befejezte a méretezést (elengedte az egeret). | Lassú műveletek (újrarajzolás, számolás), mert csak egyszer fut. |
LocationChanged, Move | Az ablak helye változott. | Hely követése, képernyőn belül tartás. |
Resize a WindowState váltáskor | Kicsinyítésnél és maximalizálásnál is lefut. | Az állapot ellenőrzése a WindowState alapján. |
private void Form1_Resize(object sender, EventArgs e)
{
// gyors: csak egy felirat (húzás közben sokszor fut)
lblMeret.Text = $"{this.ClientSize.Width} x {this.ClientSize.Height}";
if (this.WindowState == FormWindowState.Minimized)
{
return; // kicsinyített ablaknál ne számoljunk (a mérete 0 is lehet)
}
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
// lassú munka itt: egyszer fut a méretezés végén
NagyRajzFrissit();
}
private void btnTeljes_Click(object sender, EventArgs e)
{
this.WindowState = this.WindowState == FormWindowState.Maximized
? FormWindowState.Normal
: FormWindowState.Maximized;
}Resize húzás közben másodpercenként sokszor fut. Ha a kezelő lassú (nagy kép újraszámolása, adatbázis-lekérdezés), az ablak akadozik. Lassú munkára a ResizeEnd való (de a maximalizálásnál a ResizeEnd nem fut, ott a Resize vagy a SizeChanged kell).Resize eseményben ellenőrizd a WindowState értékét, mielőtt osztasz a mérettel.Jósolj!
A Resize eseményben egy másodpercig tartó számítás van. Mit tapasztalsz az ablak szélének húzásakor? Mit változtat, ha a számítást a ResizeEnd eseménybe teszed?
Jóslat ellenőrzése
A Resize esetén az ablak rendkívül lassan reagál (minden egérmozdulatnál egy másodperc), gyakorlatilag használhatatlan. A ResizeEnd esetén a húzás gördülékeny, és a számítás egyszer, a méretezés végén fut. (A kísérlethez használj System.Threading.Thread.Sleep(1000); sort számítás helyett.)
Mit tegyél ide: egy ablak a címsorral, ikonnal, és mellette a Size és ClientSize értékeit mutató felirat, hogy a különbség látszódjon.Javasolt fájlnév: winforms-6-1-size.webp · Alt szöveg: Az ablak Size és ClientSize értéke
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. A Location nem számít
this.Location = new Point(100, 100); // az ablak mégsem ott jelenik megHiba és javítás
A StartPosition nem Manual. Állítsd FormStartPosition.Manual értékre (a tervezőben vagy a konstruktorban, az InitializeComponent után), így a Location érvényesül.
2. A tartalom kilóg vagy levágódik
A vezérlőket 400 × 300-as területre terveztem, és az ablakot A Size = (400, 300) értékre állítottam, de a vezérlők alja levágódik.Ok és javítás
Size a keretet és a címsort is tartalmazza, ezért a használható terület kisebb. A tartalom méretéhez a ClientSize tulajdonságot állítsd.
3. Nem lehet kilépni a programból
this.ControlBox = false;
// de nincs kilépés gomb, és Esc kezelés sincsHiba és javítás
A ControlBox = false eltünteti a bezáró gombot is. Tegyél az ablakra egy Kilépés gombot (this.Close();), vagy kezeld az Esc billentyűt (5.4 lecke, 6.7 lecke CancelButton).
4. A tálcán más ikon látszik, mint amit beállítottam
Az ablak ikonja jó, de az EXE fájl a Fájlkezelőben az alapértelmezett ikonnal jelenik meg. Az ablak ikonja (Ok és javítás
Form.Icon) és az EXE ikonja (Project → Properties → Application → Icon) két külön beállítás. Állítsd be mindkettőt ugyanarra az .ico fájlra.
5. FileNotFoundException az ikonnál
this.Icon = new Icon("C:\\Munka\\ikon.ico"); // másik gépen nincs ilyen mappaHiba és javítás
A fix útvonal csak a fejlesztő gépén létezik. Ágyazd az ikont az erőforrások közé (Properties → Resources, vagy a tervezőben az Icon tulajdonságon át), így a programmal együtt utazik.
6. Az ablak akadozik átméretezéskor
A méret húzása közben az ablak sokat késik. A Ok és javítás
Resize kezelő lassú munkát végez (újrarajzolás, adatbetöltés), és húzás közben sokszor fut. Vidd a lassú munkát a ResizeEnd eseménybe, a Resize csak gyors frissítést (felirat) tartalmazzon.
Mini projekt: ablakbeállító
Készíts egy ablakot, amely önmagának a tulajdonságait állítja élőben, és mutatja az aktuális értékeket:
- Az ablakon:
lblInfo(az aktuálisSize,ClientSize,Location,WindowState, többsoros),cmbKeret(FormBorderStyleértékei),cmbPozicio(Középre, Bal felső sarok, Jobb alsó sarok) és egybtnPozicio,nudSzelésnudMag(ClientSize),btnMeret,trbAtlatszo(30–100, azOpacity),chkTopMost,chkTaskbar,chkMinimize,chkMaximize,txtCim(az ablak címe). - A
cmbKeretaFormBorderStylefelsorolás értékeit tartalmazza (Enum.GetNames), és a kiválasztás azonnal átállítja az ablak keretét. - A
txtCimszövege (TextChanged) azonnal az ablak címe lesz; üres cím esetén Névtelen. - A
btnMeretanudSzelésnudMagértékére állítja aClientSizetulajdonságot; aMinimumSize420 × 480, így az ablak nem lehet kisebb. - A
btnPozicioa választott helyre teszi az ablakot (a munkaterülethez igazítva,Screen.WorkingArea). - A jelölőnégyzetek a
TopMost,ShowInTaskbar,MinimizeBox,MaximizeBoxtulajdonságokat kapcsolják; atrbAtlatszoazOpacityértékét. - A
lblInfoaResizeésLocationChangedeseményre frissül, anudSzelésnudMagis követi az ablak méretét (jelzővel, hogy ne legyen hurok). - Teszteld: minden keretstílus, méret beállítása és húzása, a három pozíció, az átlátszóság, a jelölőnégyzetek, a kicsinyítés és maximalizálás.
Megoldás megnyitása (próbáld ki előbb önállóan!)
A FormBorderStyle felsorolás nevei szövegként kerülnek a listába, és a választásnál a Enum.Parse alakítja vissza a nevet értékké. A frissites jelző akadályozza meg, hogy a méret frissítése a számmezők eseményeit is lefuttassa (5.5 lecke).
private bool frissites = false;
private void Form1_Load(object sender, EventArgs e)
{
this.MinimumSize = new Size(420, 480);
cmbKeret.Items.AddRange(Enum.GetNames(typeof(FormBorderStyle)));
cmbKeret.SelectedItem = this.FormBorderStyle.ToString();
cmbPozicio.Items.AddRange(new object[] { "Középre", "Bal felső sarok", "Jobb alsó sarok" });
cmbPozicio.SelectedIndex = 0;
trbAtlatszo.Minimum = 30;
trbAtlatszo.Maximum = 100;
trbAtlatszo.Value = 100;
chkTopMost.Checked = this.TopMost;
chkTaskbar.Checked = this.ShowInTaskbar;
chkMinimize.Checked = this.MinimizeBox;
chkMaximize.Checked = this.MaximizeBox;
txtCim.Text = this.Text;
Frissit();
}
private void Frissit()
{
frissites = true;
try
{
lblInfo.Text = $"Size: {this.Width} x {this.Height}\r\n"
+ $"ClientSize: {this.ClientSize.Width} x {this.ClientSize.Height}\r\n"
+ $"Location: {this.Location.X}, {this.Location.Y}\r\n"
+ $"Állapot: {this.WindowState}";
if (this.WindowState == FormWindowState.Normal)
{
nudSzel.Value = Math.Max(nudSzel.Minimum, Math.Min(nudSzel.Maximum, this.ClientSize.Width));
nudMag.Value = Math.Max(nudMag.Minimum, Math.Min(nudMag.Maximum, this.ClientSize.Height));
}
}
finally
{
frissites = false;
}
}
private void Form1_Resize(object sender, EventArgs e)
{
Frissit();
}
private void Form1_LocationChanged(object sender, EventArgs e)
{
Frissit();
}
private void cmbKeret_SelectionChangeCommitted(object sender, EventArgs e)
{
this.FormBorderStyle = (FormBorderStyle)Enum.Parse(typeof(FormBorderStyle), cmbKeret.SelectedItem.ToString());
}
private void txtCim_TextChanged(object sender, EventArgs e)
{
this.Text = txtCim.Text.Trim().Length == 0 ? "Névtelen" : txtCim.Text;
}
private void btnMeret_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Normal;
this.ClientSize = new Size((int)nudSzel.Value, (int)nudMag.Value);
}
private void btnPozicio_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Normal;
Rectangle munka = Screen.FromControl(this).WorkingArea;
if (cmbPozicio.SelectedIndex == 0)
{
this.CenterToScreen();
}
else if (cmbPozicio.SelectedIndex == 1)
{
this.Location = new Point(munka.Left, munka.Top);
}
else
{
this.Location = new Point(munka.Right - this.Width, munka.Bottom - this.Height);
}
}
private void trbAtlatszo_Scroll(object sender, EventArgs e)
{
this.Opacity = trbAtlatszo.Value / 100.0;
}
private void chkTopMost_CheckedChanged(object sender, EventArgs e)
{
this.TopMost = chkTopMost.Checked;
}
private void chkTaskbar_CheckedChanged(object sender, EventArgs e)
{
this.ShowInTaskbar = chkTaskbar.Checked;
}
private void chkMinimize_CheckedChanged(object sender, EventArgs e)
{
this.MinimizeBox = chkMinimize.Checked;
}
private void chkMaximize_CheckedChanged(object sender, EventArgs e)
{
this.MaximizeBox = chkMaximize.Checked;
}Mit tegyél ide: a kész ablakbeállító program: a beállítóvezérlők és a feliratban a Size, ClientSize, Location és állapot értékei.Javasolt fájlnév: winforms-6-1-kesz.webp · Alt szöveg: Az ablakbeállító program
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. Értesítő ablak a jobb alsó sarokban
Készíts egy kis A tervezőben: ErtesitoAblak űrlapot, amely a képernyő munkaterületének jobb alsó sarkában jelenik meg (a tálca felett), nem kap tálcagombot, mindig felül van, és három másodperc múlva magától bezárul. Mit állítasz a tervezőben, és mit a kódban?Egy lehetséges megoldás
FormBorderStyle: FixedToolWindow (vagy None), ShowInTaskbar: False, TopMost: True, StartPosition: Manual, egy Timer (3000 ezredmásodperc, Enabled: True). A hely a Load eseményben számítható, mert csak ekkor ismert a végleges méret.private void ErtesitoAblak_Load(object sender, EventArgs e)
{
Rectangle munka = Screen.PrimaryScreen.WorkingArea;
this.Location = new Point(munka.Right - this.Width - 10, munka.Bottom - this.Height - 10);
}
private void tmrBezar_Tick(object sender, EventArgs e)
{
tmrBezar.Stop();
this.Close();
}
2. Méret a címsorban
Az ablak címe mutassa az aktuális kliensterület méretét (Szerkesztő – 640 × 420). Melyik eseményt használod, hogy az átméretezés közben is frissüljön, és ne akadozzon? A Egy lehetséges megoldás
Resize eseményt: a felirat frissítése gyors, ezért húzás közben is jó. Kicsinyített ablaknál a méret nulla, ezért kihagyjuk a frissítést.private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
return;
}
this.Text = $"Szerkesztő – {this.ClientSize.Width} × {this.ClientSize.Height}";
}
3. Ikon váltás állapotjelzésre
Az ablak ikonja zöld, ha minden rendben, piros, ha hiba van (egy Add hozzá a két chkHiba jelölőnégyzet szimulálja). Hogyan tárolod a két ikont?Egy lehetséges megoldás
.ico fájlt a projekt Properties → Resources oldalához (Add Resource → Add Existing File), és nevezd el őket (ikonZold, ikonPiros). Az erőforrás a programba épül, ezért másik gépen is működik.private void chkHiba_CheckedChanged(object sender, EventArgs e)
{
this.Icon = chkHiba.Checked ? Properties.Resources.ikonPiros : Properties.Resources.ikonZold;
this.Text = chkHiba.Checked ? "Hiba!" : "Minden rendben";
}
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. Size és ClientSize
Egy mondatban mondd el a különbséget, és hogy melyiket használnád egy 400 × 400 pixeles játéktér méretezésére. A Megoldás megnyitása
Size az ablak teljes mérete (keret és címsor is), a ClientSize a használható belső terület. A játéktérhez a ClientSize kell (ClientSize = new Size(400, 400)), így a keret vastagságától függetlenül pontosan elfér a tartalom.
2. Középre igazítás
Egy Középre gomb kattintására az ablak a képernyő közepére ugrik. Melyik metódussal, és mi a különbség a A StartPosition beállításhoz képest?Megoldás megnyitása
CenterToScreen() metódussal. A StartPosition csak az ablak induló helyét határozza meg, a CenterToScreen() bármikor, futás közben is középre teszi.private void btnKozepre_Click(object sender, EventArgs e)
{
this.CenterToScreen();
}
Közepes szint
3. Indítóképernyő
Készíts A IndulasiKep nevű keret nélküli ablakot, amely a program indulásakor két másodpercig látszik a képernyő közepén, majd a főablak nyílik meg. Hol indítod?Megoldás megnyitása
Program.cs Main metódusában, az Application.Run előtt, ShowDialog() hívással: addig vár, amíg az indítóképernyő be nem záródik (a saját Timer-e zárja be). A kép ablakának FormBorderStyle értéke None, a StartPosition CenterScreen.// Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (IndulasiKep kep = new IndulasiKep())
{
kep.ShowDialog();
}
Application.Run(new Form1());
}
// IndulasiKep.cs (tmrKep: Timer, Interval: 2000, Enabled: True)
private void tmrKep_Tick(object sender, EventArgs e)
{
tmrKep.Stop();
this.Close();
}
4. Minimális méret védelme
Egy űrlap vezérlői 600 × 400 képpontnál kisebb ablakban összezsúfolódnak. Hogyan akadályozod meg, hogy a felhasználó ennél kisebbre húzza? Mi a különbség a A Size és ClientSize megadása között ebben az esetben?Megoldás megnyitása
MinimumSize tulajdonság a teljes ablakméretre (Size) vonatkozik, nem a kliensterületre. Ha a kliensterületre akarsz garantálni egy méretet, számold ki a különbséget: this.MinimumSize = new Size(600 + (this.Width - this.ClientSize.Width), 400 + (this.Height - this.ClientSize.Height)); (a Load eseményben, mert ekkor már ismert a keret vastagsága).private void Form1_Load(object sender, EventArgs e)
{
int keretSzel = this.Width - this.ClientSize.Width;
int keretMag = this.Height - this.ClientSize.Height;
this.MinimumSize = new Size(600 + keretSzel, 400 + keretMag);
}
Kihívás szint
5. A második monitorra
Egy gomb a második monitor közepére teszi az ablakot, ha van ilyen. Ha nincs, üzenet jelenik meg. Hogyan számolod ki a középpontot? A Megoldás megnyitása
Screen.AllScreens tömb elemei a monitorok. Az ablakot a munkaterület közepére tesszük: a bal felső sarok a terület közepétől az ablak méretének fele.private void btnMasodik_Click(object sender, EventArgs e)
{
if (Screen.AllScreens.Length < 2)
{
MessageBox.Show("Csak egy monitor csatlakozik.");
return;
}
Screen aktualis = Screen.FromControl(this);
Screen masik = Screen.AllScreens[0] == aktualis ? Screen.AllScreens[1] : Screen.AllScreens[0];
Rectangle terulet = masik.WorkingArea;
this.WindowState = FormWindowState.Normal;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(
terulet.Left + (terulet.Width - this.Width) / 2,
terulet.Top + (terulet.Height - this.Height) / 2);
}
6. A képernyőn belül tartás
Az ablak nem húzható a képernyő munkaterületén kívülre: ha a felhasználó mégis oda húzná, az ablak visszaugrik a határra. Melyik eseményt használod, és mire kell vigyázni, hogy ne legyen végtelen ciklus? A Megoldás megnyitása
LocationChanged eseményt. A Location átállítása maga is kiváltja az eseményt, ezért jelző kell (5.5 lecke), különben a kezelő önmagát hívná. Maximalizált és kicsinyített ablaknál nem szabad beavatkozni.private bool igazitas = false;
private void Form1_LocationChanged(object sender, EventArgs e)
{
if (igazitas || this.WindowState != FormWindowState.Normal)
{
return;
}
Rectangle munka = Screen.FromControl(this).WorkingArea;
int x = Math.Max(munka.Left, Math.Min(this.Left, munka.Right - this.Width));
int y = Math.Max(munka.Top, Math.Min(this.Top, munka.Bottom - this.Height));
if (x != this.Left || y != this.Top)
{
igazitas = true;
try
{
this.Location = new Point(x, y);
}
finally
{
igazitas = false;
}
}
}
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. A Ha a A képernyő munkaterülete a tálca nélkül. Az ablak igazításánál ezt használd. Nem méretezhető, párbeszédablak-szerű keret, általában csak bezáró gombbal és ikon nélkül. A bezáró gomb is eltűnik. Ha nincs más kilépési lehetőség (gomb, Az ablak ikonját a Lassú műveletekhez, mert a 1. Mi a különbség a Size és a ClientSize között?
Size a teljes ablak (keret, címsor), a ClientSize a belső használható terület.2. Mikor számít a Location?
StartPosition értéke Manual. Más értéknél az induló helyet a StartPosition határozza meg.3. Mi a Screen.WorkingArea?
4. Mit jelent a FormBorderStyle.FixedDialog?
5. Miért veszélyes a ControlBox = false?
Esc), a felhasználó nem tudja bezárni az ablakot.6. Mi a különbség az ablak és az EXE ikonja között?
Form.Icon, az EXE fájl ikonját a projekt Application → Icon beállítása adja. Két külön beállítás.7. Mikor használd a ResizeEnd eseményt a Resize helyett?
Resize húzás közben sokszor, a ResizeEnd csak a méretezés végén egyszer fut. (Maximalizálásnál a ResizeEnd nem fut.)
Mit tudsz már?
- Megkülönbözteted a
Sizeés aClientSizetulajdonságot. - Beállítod az ablak helyét, méretkorlátját, keretstílusát és a címsor gombjait.
- Dinamikus címet írsz, és ikont állítasz be (tervezőben, erőforrásból).
- Kezeled az ablak állapotát és a méretváltozás eseményeit.
- Felismered a gyakori hibákat (
Location/StartPosition,ControlBoxzsákutca, ikon útvonala).
Következő lecke: Anchor és Dock beállítások
Az ablak méretét már tudod állítani. A következő leckében a vezérlők követik az ablak méretét: így lesz az űrlap átméretezhető és igényes.




