Grafikus C# – Windows Forms tanfolyam › 6.8 lecke

Windows Forms · 6.8 lecke · méretezhetőség

Méretezhetőség, DPI és betűméret

Amit a te monitorodon tökéletesnek látsz, a diák régi laptopján szétcsúszhat, egy 4K-s kijelzőn parányi lehet, és egy nagyobb betűméretet használó felhasználónál a címkék levágódnak. A Windows Forms program különböző képernyő-méretezésen (DPI: 100%, 125%, 150%, 200%) és betűméreten fut, és a jó űrlap mindegyiken rendezett. Ebben a leckében megtanulod az automatikus skálázást (AutoScaleMode), a DPI fogalmát, a betű öröklődését (Font), és azt, hogyan készíts olyan elrendezést, amely a fix pixelek helyett a tartalomhoz igazodik (AutoSize, PreferredSize, 6.4 lecke).

  • kb. 100 perc
  • közepes szint
  • DPI és betűméret
Anime stílusú fiú és lány egy C# programozási feladatot beszél meg

A lecke végére

  • érted a DPI és a képernyő-méretezés fogalmát, és tudod, miért kell vele számolni;
  • ismered az AutoScaleMode módjait (Font, Dpi, None) és az AutoScaleDimensions szerepét;
  • tudod, hogy a Font tulajdonság öröklődik, és az ablak betűjének módosítása az egész felületet méretezi;
  • fix koordináták helyett tartalomhoz igazodó elrendezést készítesz (AutoSize, TableLayoutPanel, GetPreferredSize);
  • kódból létrehozott vezérlők méretét a DPI szerint számolod át;
  • teszteled az űrlapot több méretezésen és betűmérettel, és felismered a „DPI csapdát” a tervezésnél.

Mielőtt elkezded

Ehhez a leckéhez a 6.2–6.4 lecke (Anchor, Dock, TableLayoutPanel) és a 6.1 lecke (Size, ClientSize) szükséges. Ha teheted, próbáld ki a példákat különböző Windows-skálázás mellett (Beállítások → Rendszer → Megjelenítés → Méretezés).

6.7 AcceptButton és CancelButton →

DPI és a képernyő-méretezés

A DPI (dots per inch, képpont/hüvelyk) azt mutatja, hány képpont jut egy fizikai hüvelykre. A Windows hagyományos alapja a 96 DPI (100%-os méretezés). A nagy felbontású, kis méretű kijelzőkön (laptop, 4K) a 96 DPI-s program parányi lenne, ezért a Windows méretezést (scaling) ajánl: 125%-nál 120 DPI, 150%-nál 144 DPI, 200%-nál 192 DPI a program számára.

Windows méretezésDPIEgy „100%-os” 100 képpontos vezérlő valós mérete
100%96100 képpont
125%120125 képpont
150%144150 képpont
200%192200 képpont
Miért gond?A tervezőben a vezérlők mérete képpontban van megadva (Width = 100). Ha a DPI nagyobb, ugyanezt a méretet nagyobbra kell átszámolni, különben minden apró lesz, és a szövegek (amelyek a DPI-vel nőnek) kinőnek a fix méretű vezérlőkből.
Logikai és fizikai képpontA „logikai” képpont a 96 DPI-s tervezési egység, a „fizikai” a valós képpont. A kettő aránya: DPI / 96.
Bitmap-skálázásHa a program nem DPI-tudatos, a Windows nagyítja az egész ablak képét: nem torzul az elrendezés, de a szöveg elmosódott. A DPI-tudatos program maga számolja át a méreteket, és éles marad.
Több monitorEgy ablak több, eltérő DPI-jű monitor között húzva váltogathatja a méretezést (Per-Monitor DPI). A modern .NET ezt kezelni tudja, de külön beállítás kell hozzá.
Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
// az ablak DPI értéke (.NET Framework 4.7-től és a modern .NET-ben elérhető)
lblInfo.Text = $"DPI: {this.DeviceDpi} ({this.DeviceDpi / 96.0:P0} méretezés)";

// ugyanezt a Graphics objektum is megadja
using (Graphics g = this.CreateGraphics())
{
lblInfo.Text += $"\r\nGraphics DPI: {g.DpiX}";
}
}

Jósolj!

Egy gombot kódból hozol létre: gomb.Size = new Size(120, 30);. A felhasználó gépén 150%-os a Windows-méretezés, a programod DPI-tudatos, a többi vezérlő automatikusan megnő. Mekkora lesz a gomb a többi vezérlőhöz képest?

Jóslat ellenőrzése

A gomb kisebb lesz a többinél: a kódban megadott 120 × 30 az már fizikai képpont, nem skálázódik, miközben a tervezőben létrehozott vezérlők 150%-ra nőnek. A kódból létrehozott vezérlők méretét a DPI szerint kell átszámolni (lásd lent), vagy olyan elrendezésbe kell tenni, amely a tartalomhoz igazodik (AutoSize, TableLayoutPanel). Az újabb .NET-verziók egyes esetekben automatikusan skálázzák az utólag hozzáadott vezérlőket, ezért a pontos viselkedést a saját projektedben próbáld ki.

AutoScaleMode és AutoScaleDimensions

Az ablak két tulajdonsága szabályozza az automatikus skálázást, és a Form1.Designer.cs fájlban is látszik (InitializeComponent):

AutoScaleModeJelentése
FontA méretezés az ablak betűjének mérete szerint történik (a betű átlagos karakterszélességéhez és magasságához viszonyítva). Betűméret-változásnál (Windows szövegméret) is skáláz. A hagyományos .NET Framework sablon alapja.
DpiA méretezés a képernyő DPI értéke szerint történik, a betűtől független. Kiszámíthatóbb: a megjelenés nem függ a betűtípustól. (A modern .NET sablonja is a Font módot állítja be alapértéknek, a Dpi módot kifejezetten át kell állítani.)
InheritA szülő beállítását örökli (egy UserControl alapértéke).
NoneNincs automatikus skálázás: a vezérlők a megadott méretüket tartják.
Form1.Designer.cs (részlet, a tervező generálja)C#
// .NET Framework (Font mód)
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

// újabb .NET (Font mód 9 pontos Segoe UI betűvel)
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

// DPI mód
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
AutoScaleDimensionsA tervezéskor érvényes referencia: a futásidejű méret és ez aránya adja a skálázási tényezőt. Ezt ne módosítsd kézzel: a tervező írja, és a hibás érték az egész ablakot elcsúsztatja.
Melyiket válaszd?Új projektnél a sablon alapértékét tartsd meg. A Font mód a Windows szövegméret-beállításához igazodik (ez az akadálymentesség szempontjából előnyös), a Dpi mód kiszámíthatóbb. Egy projektben minden ablakon és felhasználói vezérlőn ugyanaz legyen.
Vegyes módokHa egy ablak Font, a benne lévő UserControl Dpi módú, a méretek elcsúszhatnak. Egységesíts.
A DPI csapda a tervezéskorHa a tervezőt más DPI-jű gépen nyitod meg (150%-os laptop és 100%-os monitor között váltogatva), a Visual Studio a vezérlők méretét átszámolhatja, és a Designer.cs fájlba a már skálázott értékeket írhatja. Így az ablak a következő nyitáskor „nagyobb” lesz, és a skálázás duplán érvényesül. Tervezz mindig ugyanazon a DPI-n (lehetőleg 100%-on), és a verziókezelés különbségeiben ellenőrizd, hogy a méretek hirtelen nem nőttek-e meg.

Jósolj!

A projekt AutoScaleMode értéke None. A program egy 150%-os méretezésű gépen fut (DPI-tudatos módban). Mit tapasztalsz az ablak vezérlőin?

Jóslat ellenőrzése

A vezérlők nem nőnek meg (a mérete képpontban rögzített), de a szöveg a nagyobb DPI miatt igen: a szövegek kinőnek a vezérlőkből, a címkék és gombok szövege levágódik. Ezért a None csak akkor jó, ha minden elrendezés tartalomhoz igazodó (AutoSize, TableLayoutPanel), vagy ha a program nem DPI-tudatos, és a Windows nagyítja a képet.

A Font öröklődik: egy betű az egész felületre

A Font egy ambient (környezeti) tulajdonság: ha egy vezérlőnek nincs saját betűje beállítva, a szülőjétől örökli. Az ablak Font értékét módosítva az összes vezérlő betűje megváltozik (a saját betűvel rendelkezők kivételével). Két fontos következmény van:

Form1.csC#
// 1. egységes, rendszerhez illő betű az egész ablaknak
this.Font = SystemFonts.MessageBoxFont; // a Windows üzenetablakainak betűje (Segoe UI 9pt)

// 2. betűméret-választás a felhasználónak: az egész felület méretezhető
private void BetuMeret(float pont)
{
this.SuspendLayout();
this.Font = new Font(this.Font.FontFamily, pont);
this.ResumeLayout(true);
}

// 3. egy vezérlő kivétele: saját betűje van, nem örököl
lblCim.Font = new Font(this.Font.FontFamily, this.Font.Size * 1.5f, FontStyle.Bold); // a cím az ablak betűjéhez igazodik
Relatív méretA címet ne fix 14 pontosra állítsd, hanem az ablak betűméretének többszörösére (this.Font.Size * 1.5f), így az ablak betűméretének változásakor a cím is arányosan nő. A fix betűméretű vezérlő a többitől eltér.
Az új Font példányA Font objektumok nem módosíthatók: új példányt kell létrehozni (new Font(...)). Az új példány felszabadítása (Dispose) a régit illeti, ha már nem használod (a modern kód ezt a using blokkal vagy a garbage collectorra bízza).
A Windows szövegméretA Windows Beállítások → Kisegítő lehetőségek → Szövegméret a rendszerbetűket méretezi (SystemFonts), ezért az AutoScaleMode.Font és a rendszerbetű használata együtt követi a felhasználó igényét.
SuspendLayout a Font módosításnálA betűváltás minden vezérlő újrarendezését kiváltja. A SuspendLayout/ResumeLayout páros a villogást és a lassulást csökkenti.

Jósolj!

Az ablak Font értékét 9-ről 14 pontra állítod. A lblCim címkének saját, fix 12 pontos betűje van. Milyen lesz a címke a többi szöveghez képest?

Jóslat ellenőrzése

A címke kisebb betűvel marad (12 pont), miközben a többi szöveg 14 pontos lett: a cím a törzsszövegnél kisebb, ami furcsa. A fix betűméretű vezérlő nem követi az ablak betűjét. A megoldás a relatív méret: this.Font.Size * 1.5f az ablak betűméretének megváltozásakor újra beállítva.

Tartalomhoz igazodó elrendezés

A legbiztosabb védekezés a fix pixelek ellen: az elrendezés a tartalom méretéhez igazodik. A korábbi leckék eszközei ezt tudják:

EszközMit tesz?
AutoSize = true (Label, Button, Panel, Form)A vezérlő mérete a tartalmához (szöveg, gyermekek) igazodik.
AutoSizeMode = GrowAndShrinkA vezérlő a tartalommal együtt nő és csökken (a GrowOnly csak nő).
TableLayoutPanel AutoSize sorokkal/oszlopokkal (6.4)A rács a tartalom szerint méretez: nagyobb betűnél a sorok magasabbak lesznek.
Anchor, Dock (6.2)A vezérlő az ablakhoz igazodik, nem a fix koordinátához.
MaximumSize + AutoSize a LabelenA hosszú szöveg tördelődik egy megadott szélességen (a magasság nő).
AutoEllipsis = trueA túl hosszú szöveg végén „…” jelenik meg (a teljes szöveg ToolTip-ben).
Form1.csC#
// tördelődő hosszú címke
lblLeiras.AutoSize = true;
lblLeiras.MaximumSize = new Size(this.ClientSize.Width - 40, 0); // 0: a magasság nincs korlátozva

// a levágott szöveg jelzése és megjelenítése
btnHosszu.AutoEllipsis = true;
ttSugo.SetToolTip(btnHosszu, btnHosszu.Text);

// az ablak minimális mérete a tartalomból (a rács kívánt mérete + az ablak keretei)
Size kivant = tlp.GetPreferredSize(Size.Empty);
int keretSzel = this.Width - this.ClientSize.Width;
int keretMag = this.Height - this.ClientSize.Height;
this.MinimumSize = new Size(kivant.Width + keretSzel, kivant.Height + keretMag);

// kódból létrehozott vezérlő mérete a DPI szerint átszámolva
private int Px(int logikus)
{
return (int)Math.Round(logikus * this.DeviceDpi / 96.0);
}

gomb.Size = new Size(Px(120), Px(30));
GetPreferredSizeA vezérlő „kívánt” mérete a tartalma alapján: egy TableLayoutPanel a sorainak és oszlopainak összegét adja. Ebből számolható az ablak értelmes minimális mérete (6.1 lecke).
Px(logikus)A kódban a 96 DPI-re tervezett méreteket (a „logikai” képpontot) a DeviceDpi / 96 aránnyal szorozzuk. Így a kódból létrehozott vezérlők is arányosak a tervezőbelivel. (A .NET újabb verziói a LogicalToDeviceUnits metódust is kínálják.)
MaximumSize (szélesség, 0)A 0 érték a magasságnál azt jelenti: nincs korlát. A címke a megadott szélességnél tördel, és magasabb lesz.
Ne az ablakot méretezd előre fixreA this.Size = new Size(800, 600) fix méretet ad. Jobb a tartalomból számolt minimum és a szabad méretezhetőség (Anchor/Dock).

Jósolj!

Egy Label AutoSize értéke igaz, és hosszú szöveget tartalmaz (200 karakter), de a MaximumSize nincs beállítva. Mi történik a szöveggel egy 400 képpont széles ablakban?

Jóslat ellenőrzése

A címke egyetlen hosszú sorban nő, és az ablak jobb szélén túl kilóg (levágódik). Az AutoSize a tartalomhoz igazodik, de a tördeléshez szélességi korlát kell: a MaximumSize = new Size(szélesség, 0) beállítással a szöveg a megadott szélességnél tördelődik.

Tesztelés: több méretezés és betűméret

A méretezhetőség hibái csak más környezetben jelennek meg, ezért tudatosan tesztelj. Egy egyszerű módszer (nem kell hozzá több gép):

  1. Windows méretezés: Beállítások → Rendszer → Megjelenítés → Méretezés: 100%, 125%, 150%. A módosítás után általában ki- és bejelentkezés szükséges. Indítsd el a programot mindegyiken.
  2. Szövegméret: Beállítások → Kisegítő lehetőségek → Szövegméret: 100% és 150%. Különösen az AutoScaleMode.Font módnál lényeges.
  3. Kis ablak: méretezd át az ablakot a minimumra: nincs átlapolódás és levágott szöveg?
  4. Nagy képernyő és kicsi képernyő: a 768 képpont magas laptopon (1366 × 768) is elfér az ablak?
  5. Ellenőrző lista: a címkék, gombok és mezők szövege teljes? A gombok és a mezők nem lapolódnak át? A képek élesek? A kódból létrehozott vezérlők arányosak?

Ha az ablak nagyobb a képernyőnél

Nagy betű- vagy DPI-értéknél egy túl nagy ablak nem fér a képernyőre. Az AutoScroll = true beállítás görgetősávot ad az ablaknak (és a paneleknek), ha a tartalom nem fér el, így a program használható marad. A MaximumSize beállításával az ablakot a képernyő munkaterületére korlátozhatod (Screen.WorkingArea, 6.1 lecke).

DPI-tudatosság: élesen vagy elmosódva?

Ha a program nem DPI-tudatos, a Windows a kész ablakot kinagyítja: az elrendezés megmarad, de a szöveg elmosódott. A DPI-tudatos mód beállítása a projekttípustól függ:

  • .NET Framework: az app.manifest fájl dpiAware (true) vagy dpiAwareness (PerMonitorV2) beállítása, újabb keretrendszer-verziónál (4.7+) a App.config kiegészítései is szükségesek.
  • .NET (modern): a projektfájlban az <ApplicationHighDpiMode> tulajdonság (például SystemAware, PerMonitorV2), vagy a Program.cs elején az Application.SetHighDpiMode(HighDpiMode.SystemAware); hívás (az Application.Run előtt).

A pontos lépéseket a használt Visual Studio és .NET verzió szerint érdemes ellenőrizni (a modern sablonok már jó alapbeállítással indulnak). Nem kell az egész beállítást fejből tudnod: a lényeg az, hogy ismered a jelenséget (elmosódott szöveg), és tudod, hol keress megoldást.

📷 Képernyőkép helye

Mit tegyél ide: két képernyőkép ugyanarról a programról 100%-os és 150%-os méretezésnél: a jól felépített elrendezés mindkettőn rendezett.Javasolt fájlnév: winforms-6-8-dpi.webp · Alt szöveg: Egy űrlap két képernyő-méretezésnél

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 szöveg levágódik 125%-os méretezésnél

Egy gomb felirata csonka, a címke vége hiányzik.

Ok és javítás

A vezérlő fix méretű (AutoSize = false), a szöveg viszont a DPI-vel nő. Használj AutoSize = true vezérlőket vagy TableLayoutPanel AutoSize sorokkal/oszlopokkal, és hagyj helyet a szövegnek.

2. Az ablak a következő megnyitáskor nagyobb

A tervezőben megnyitva az ablak minden alkalommal nagyobb lesz, a vezérlők méretei megnőttek.

Ok és javítás

A „DPI csapda”: a tervezőt eltérő méretezésű gépen vagy beállításnál nyitottad, és a Designer.cs a skálázott értékeket mentette. Tedd vissza a fájlt verziókezelésből (vagy mentésből), és tervezz mindig ugyanazon a DPI-n (100%).

3. A kódból létrehozott gomb apró a többi mellett

gomb.Size = new Size(120, 30);   // 150%-nál kisebb a tervezőbelieknél
Hiba és javítás

A kódban megadott méret nem skálázódik. Számold át a DPI szerint (Px(120)), vagy hagyd az AutoSize értékét igazra, és a gombot tedd tartalomhoz igazodó tárolóba (FlowLayoutPanel).

4. Elmosódott szöveg a nagy képernyőn

A program 4K-s monitoron homályos.

Ok és javítás

A program nem DPI-tudatos, ezért a Windows nagyítja a képet. Állítsd be a DPI-tudatos módot (app.manifest vagy ApplicationHighDpiMode), és ellenőrizd, hogy az elrendezés ekkor is rendezett.

5. Nem fér ki a képernyőn

Egy nagyobb betűméretnél az ablak alja a képernyőn kívülre kerül.

Ok és javítás

Az ablak és a tartalma nagyobb a munkaterületnél. Kapcsold be az AutoScroll tulajdonságot, vagy korlátozd az ablakot a munkaterületre (MaximumSize), és tervezd úgy az elrendezést, hogy a fontos elemek a görgetés nélküli részen legyenek.

6. A cím nem nő a betűvel

lblCim.Font = new Font("Segoe UI", 16, FontStyle.Bold);   // fix 16 pont
Hiba és javítás

A fix betűméret nem követi az ablak Font értékének változását. Számold az ablak betűjéhez viszonyítva: new Font(this.Font.FontFamily, this.Font.Size * 1.6f, FontStyle.Bold), és az ablak betűjének módosításakor állítsd újra.

Mini projekt: méretezéskísérleti űrlap

Készíts programot, amely egymás mellett mutatja egy jól és egy rosszul felépített űrlap viselkedését betűméret- és DPI-változásra:

  1. Az ablak: felül egy vezérlősor (FlowLayoutPanel flpVezerlok, AutoSize) a nudBetu (NumericUpDown, 8–24, alap: 9), a btnMinimum (Legkisebb méret) és lblInfo (DPI, méretezés, betűméret, AutoScaleMode) vezérlőkkel. Alatta egy SplitContainer (split, Dock = Fill).
  2. A bal oldali panelben a jól felépített űrlap: egy TableLayoutPanel (tlpJo, Dock = Fill, két oszlop: AutoSize, Percent 100) Név, E-mail és Megjegyzés sorral, címkékkel (Anchor = Left) és mezőkkel (Dock = Fill), alul egy Küldés gombbal.
  3. A jobb oldali panelben a rosszul felépített űrlap: ugyanezek a vezérlők fix Location és Size értékekkel, AutoSize = false címkékkel és gombbal, egy hosszú címkével (Kérjük, add meg az adataidat, hogy kapcsolatba léphessünk veled) rögzített szélességgel.
  4. A nudBetu értékének változása az ablak Font értékét állítja (az egész felület betűje), SuspendLayout/ResumeLayout között. A lblInfo frissül.
  5. A btnMinimum az ablak MinimumSize értékét a jó űrlap kívánt méretéből (GetPreferredSize) számolja, és a méretet erre állítja.
  6. Egy chkAuto jelölőnégyzet a hosszú címke AutoSize és MaximumSize beállítását kapcsolja (tördelés), hogy a javítás hatása látható legyen.
  7. Teszteld: a betűméret emelése 9-ről 16-ra (melyik oldal romlik el?), az ablak átméretezése, a Windows méretezés váltása (ha tudod), a tördelés bekapcsolása.
Megoldás megnyitása (próbáld ki előbb önállóan!)

A rosszul felépített panel vezérlőit a tervezőben fix pozícióval helyezd el, vagy kódból hozd létre. A jelentős különbség a nudBetu emelésekor látszik: a bal oldali rács a sorokkal együtt nő, a jobb oldali vezérlők a helyükön maradnak, és a szöveg kilóg belőlük.

Form1.csC#
private bool frissites = false;

private void Form1_Load(object sender, EventArgs e)
{
nudBetu.Minimum = 8;
nudBetu.Maximum = 24;
nudBetu.Value = (decimal)Math.Round(this.Font.Size);
Info();
}

private void Info()
{
lblInfo.Text = $"DPI: {this.DeviceDpi} ({this.DeviceDpi / 96.0:P0}) | Betű: {this.Font.Size:0.#} pt | AutoScaleMode: {this.AutoScaleMode}";
}

private void nudBetu_ValueChanged(object sender, EventArgs e)
{
if (frissites)
{
return;
}

this.SuspendLayout();

try
{
this.Font = new Font(this.Font.FontFamily, (float)nudBetu.Value);
}
finally
{
this.ResumeLayout(true);
}

Info();
}

private void btnMinimum_Click(object sender, EventArgs e)
{
Size kivant = tlpJo.GetPreferredSize(Size.Empty);
int keretSzel = this.Width - this.ClientSize.Width;
int keretMag = this.Height - this.ClientSize.Height;

// a rács kívánt mérete + a felső sáv + az elválasztó panelek helye (közelítés)
int szel = kivant.Width * 2 + keretSzel + 40;
int mag = kivant.Height + flpVezerlok.Height + keretMag + 40;

this.MinimumSize = new Size(szel, mag);
this.Size = this.MinimumSize;
}

private void chkAuto_CheckedChanged(object sender, EventArgs e)
{
lblHosszu.AutoSize = chkAuto.Checked;

if (chkAuto.Checked)
{
lblHosszu.MaximumSize = new Size(split.Panel2.ClientSize.Width - 20, 0);
}
else
{
lblHosszu.MaximumSize = Size.Empty;
lblHosszu.Size = new Size(200, 20);
}
}
📷 Képernyőkép helye

Mit tegyél ide: a kísérleti program 16 pontos betűvel: a bal oldali rács rendezett, a jobb oldali vezérlők szövege levágott.Javasolt fájlnév: winforms-6-8-kesz.webp · Alt szöveg: A jól és rosszul felépített űrlap nagy betűmérettel

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. Kódból létrehozott gombsor DPI-hez igazítva

Hozz létre kódból öt gombot egymás mellett 100 képpontos közökkel (96 DPI-re tervezve). Hogyan számolod át a méreteket és a helyeket a DPI-hez, és miért jobb ez a FlowLayoutPanel-nél kevésbé?

Egy lehetséges megoldás

A Px segédfüggvény átszámolja a logikai méreteket. A FlowLayoutPanel még egyszerűbb: nem kell koordinátát számolni, mert az AutoSize gombok a tartalomhoz igazodnak. A kézi számolás akkor kell, ha a pontos elrendezés a feladat része.

Form1.csC#
private int Px(int logikus)
{
return (int)Math.Round(logikus * this.DeviceDpi / 96.0);
}

private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
Button gomb = new Button();
gomb.Text = "Gomb " + (i + 1);
gomb.Size = new Size(Px(90), Px(30));
gomb.Location = new Point(Px(10 + i * 100), Px(10));
this.Controls.Add(gomb);
}
}

2. Tördelődő súgószöveg

Egy súgószöveg-címke (lblSugo) hosszú magyarázatot mutat, amely az ablak szélességéhez igazodva tördelődik, és az ablak átméretezésekor újraigazodik. Mely beállítások és esemény szükségesek?

Egy lehetséges megoldás

Az AutoSize = true és a MaximumSize szélessége az ablak szélességéhez kötve, a Resize eseményben frissítve. Ez egy olyan eset, ahol az Anchor nem elég, mert a magasság is változik.

Form1.csC#
private void SugoIgazit()
{
lblSugo.AutoSize = true;
lblSugo.MaximumSize = new Size(this.ClientSize.Width - lblSugo.Left - 12, 0);
}

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

private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState != FormWindowState.Minimized)
{
SugoIgazit();
}
}

3. Hosszú szöveg gombon

Egy keskeny gombon hosszú felirat van (Az összes kijelölt elem exportálása). Mutasd meg az AutoEllipsis és a ToolTip együttes használatát. Mikor jobb inkább a gombot szélesíteni?

Egy lehetséges megoldás

Az AutoEllipsis a levágott szöveg végére „…” jelet tesz, a ToolTip mutatja a teljes szöveget. A fontos feliratot azonban nem szabad levágni: ott a gomb legyen AutoSize, vagy a szöveget rövidítsd.

Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
btnExport.Text = "Az összes kijelölt elem exportálása";
btnExport.AutoEllipsis = true;
btnExport.Width = 150;

ttSugo.SetToolTip(btnExport, btnExport.Text);
}

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. AutoScaleMode

Mi a különbség a Font és a Dpi mód között, és mit jelent a None?

Megoldás megnyitása

A Font mód a betű méretéhez, a Dpi mód a képernyő DPI értékéhez igazítja a méreteket. A None nem skáláz: a vezérlők fix méretűek maradnak, miközben a szöveg a DPI-vel nő, ezért levágódhat.

2. Ambient Font

Az ablak betűjét 12 pontra állítod. Melyik vezérlők betűje változik meg, és melyiké nem?

Megoldás megnyitása

Mindazoké, amelyeknek nincs saját Font értéke beállítva (öröklik az ablak betűjét). Azok maradnak, amelyeknek a Font tulajdonságát kifejezetten módosítottad a tervezőben vagy a kódban.

Közepes szint

3. Minimális méret a tartalomból

Számold ki a GetPreferredSize segítségével egy TableLayoutPanel kívánt méretét, és állítsd be belőle az ablak MinimumSize értékét. Mire kell vigyáznod a keret vastagságánál?

Megoldás megnyitása

A kívánt méret a kliensterületre vonatkozik, ezért hozzá kell adni az ablak keretének és címsorának méretét (Size - ClientSize), hogy a MinimumSize (amely a teljes ablak mérete) helyes legyen.

Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
Size kivant = tlp.GetPreferredSize(Size.Empty);

int keretSzel = this.Width - this.ClientSize.Width;
int keretMag = this.Height - this.ClientSize.Height;

this.MinimumSize = new Size(kivant.Width + keretSzel, kivant.Height + keretMag);
}

4. Ikon a DPI szerint

Egy gombon 16 képpontos ikon van 96 DPI-nél. Magasabb DPI-nél élesebb kell. Hogyan választasz a kisebb és nagyobb ikon között a DeviceDpi alapján?

Megoldás megnyitása

Két (vagy három) méretű ikont tárolsz erőforrásban (16, 24, 32 képpont), és a DPI szerint választasz: a nagyítás helyett az éles nagyobb kép jobb. A kiválasztás küszöbértékekkel történik.

Form1.csC#
private Image IkonValaszt()
{
if (this.DeviceDpi >= 192)
{
return Properties.Resources.Ikon32;
}

if (this.DeviceDpi >= 120)
{
return Properties.Resources.Ikon24;
}

return Properties.Resources.Ikon16;
}

private void Form1_Load(object sender, EventArgs e)
{
btnMent.Image = IkonValaszt();
}

Kihívás szint

5. A betűméret megjegyzése

A felhasználó által választott betűméret (nudBetu) maradjon meg a következő indításig. Hogyan oldod meg az 5.6 lecke eszközeivel, és mire kell vigyázni az érvénytelen mentett értéknél?

Megoldás megnyitása

A Settings egy float típusú BetuMeret beállítást tárol. A Load betöltésnél ellenőrizd a tartományt (8–24), különben egy hibás érték használhatatlan felületet adhat.

Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
float mentett = Properties.Settings.Default.BetuMeret;

if (mentett >= 8 && mentett <= 24)
{
this.Font = new Font(this.Font.FontFamily, mentett);
}

nudBetu.Value = (decimal)this.Font.Size;
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Properties.Settings.Default.BetuMeret = this.Font.Size;
Properties.Settings.Default.Save();
}

6. Tesztlista a méretezhetőséghez

Írj tesztlistát (táblázatot) egy űrlap méretezhetőségének ellenőrzéséhez: legalább 6 sor (teszt, lépések, elvárt eredmény), a 4.7 lecke tesztterv-sablonja alapján.

Megoldás megnyitása
#TesztLépésekVárt eredmény
1100% méretezésIndítsd a programot 100%-os Windows-méretezésnél.Minden szöveg teljes, nincs átlapolódás.
2125% és 150%Állítsd át a méretezést, jelentkezz be újra, indítsd el.Az elrendezés rendezett, a szöveg éles (DPI-tudatos mód).
3Nagy szövegméretKisegítő lehetőségek: szövegméret 150%.A felület követi (AutoScaleMode.Font), nincs levágott szöveg.
4Minimális ablakHúzd az ablakot a lehető legkisebbre.A tartalom nem lapolódik át; a MinimumSize megállítja.
5Kis képernyőFuttasd 1366 × 768 felbontáson.Az ablak elfér, vagy görgethető (AutoScroll).
6Kódból létrehozott vezérlőkNyisd meg az ablakot 150%-nál.A dinamikus vezérlők mérete arányos a tervezőbeliekkel.

Gyors önellenőrzés

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

1. Mi a DPI, és mi a 96 DPI?

Képpont per hüvelyk. A 96 DPI a Windows alapja (100%-os méretezés), a többi méretezés ennek többszöröse (125% = 120 DPI).

2. Mit szabályoz az AutoScaleMode?

Hogyan skálázódnak a vezérlők a DPI vagy a betűméret változásakor (Font, Dpi, None).

3. Mit jelent, hogy a Font ambient tulajdonság?

A vezérlő a szülőjétől örökli, ha saját értéke nincs beállítva: az ablak betűjének módosítása az egész felületre kihat.

4. Mi a DPI csapda a tervezéskor?

Eltérő DPI-jű gépen megnyitott tervező a skálázott méreteket mentheti a Designer.cs fájlba, ezért az ablak nagyobb lesz. Tervezz mindig ugyanazon a DPI-n.

5. Miért nem skálázódik a kódban megadott méret?

Mert fizikai képpont, nem logikai. A DPI szerint kell átszámolni (DeviceDpi / 96.0), vagy tartalomhoz igazodó tárolót használni.

6. Hogyan tördelsz egy hosszú címkét?

AutoSize = true és MaximumSize = new Size(szélesség, 0).

7. Mi az elmosódott szöveg oka nagy képernyőn?

A program nem DPI-tudatos: a Windows nagyítja a kész képet. DPI-tudatos módra kell állítani.

Mit tudsz már?

  • Érted a DPI és az automatikus skálázás fogalmát (AutoScaleMode).
  • Tudod, hogy a Font öröklődik, és az ablak betűjével az egész felület méretezhető.
  • Tartalomhoz igazodó elrendezést készítesz, és a kódból létrehozott vezérlőket a DPI szerint számolod át.
  • Teszteled az űrlapot több méretezésen és betűmérettel.
  • Felismered a gyakori hibákat (DPI csapda, levágott szöveg, fix betűméret).

Következő lecke: Hozzáférhetőség – kontraszt, feliratok, használhatóság

A program mindenki számára használható: színkontraszt, feliratok, képernyőolvasó támogatás és a hozzáférhető űrlap szabályai.