Grafikus C# – Windows Forms tanfolyam › 6.9 lecke Windows Forms · 6.9 lecke · hozzáférhetőség A program akkor jó, ha mindenki tudja használni: a gyengén látó, a színtévesztő, a csak billentyűzettel dolgozó, a képernyőolvasót használó felhasználó, és az is, aki napfényben, egy kézzel, siet. Ezt hívjuk hozzáférhetőségnek (accessibility, röviden a11y). Tanárként különösen fontos: egy osztályban mindig vannak diákok különleges igényekkel. Ebben a leckében megtanulod a színkontraszt számítását, a nem csak színnel való jelzést, a vezérlők feliratozását és az Hozzáférhetőség: kontraszt, feliratok és használhatóság
AccessibleName használatát, a magas kontrasztú mód kezelését, és elkészíted egy egyszerű ellenőrző programot, amely egy űrlap hiányosságait feltárja.
A lecke végére
- kiszámolod két szín kontrasztarányát, és tudod a megfelelőségi küszöböket (4,5 : 1 és 3 : 1);
- az információt nem csak színnel jelzed (szöveg, jel, alak);
- minden beviteli mezőnek címkét adsz, és az
AccessibleName,AccessibleDescriptionértékekkel segíted a képernyőolvasót; - a
SystemColorsés aSystemInformation.HighContrastsegítségével kezeled a magas kontrasztú módot; - biztosítod a billentyűzetes használatot és az érthető üzeneteket;
- eszközökkel és egyszerű teszttel ellenőrzöd a hozzáférhetőséget.
Mielőtt elkezded
Ehhez a leckéhez a 6.6 lecke (fókusz, címkék, ErrorProvider), a 6.8 lecke (betűméret, tartalomhoz igazodás), az 5.8 lecke (rekurzív bejárás) és az 1.11 lecke (ToolTip) szükséges. Új projektben próbáld ki a példákat.
Miért fontos, és mit jelent?
A hozzáférhetőség nem „extra”, hanem a használhatóság része. Sokan érintettek: a látássérültek (gyengénlátók, vakok), a színtévesztők (a férfiak mintegy 8%-a valamilyen mértékben), a mozgássérültek (akik nem tudnak egeret használni), a hallássérültek (akik nem hallják a hangjelzéseket), és bárki, aki ideiglenes helyzetben van (törött kéz, erős napfény, fáradtság). A nemzetközi irányelv, a WCAG (Web Content Accessibility Guidelines) négy alapelvet fogalmaz meg, amelyek asztali programokra is vonatkoztathatók:
| Alapelv | Jelentése | Példa Windows Formsban |
|---|---|---|
| Érzékelhető | Az információ többféleképp is megjelenik. | Hibaüzenet szöveggel és jellel, nem csak piros színnel. |
| Működtethető | Minden funkció billentyűzettel is elérhető. | Logikus Tab sorrend, mnemonikus betűk, nincs fókuszcsapda. |
| Érthető | Egyértelmű feliratok és üzenetek. | „A név kötelező.” a „Hiba 17” helyett. |
| Robusztus | Együttműködik a segítő eszközökkel. | Valódi vezérlők használata, AccessibleName. |
A Windows Forms vezérlők alapból hozzáférhetők
A beépített vezérlők (Button, TextBox, CheckBox, ComboBox) a Windows UI Automation és MSAA technológiáin keresztül kapcsolódnak a képernyőolvasókhoz (Narrator, NVDA, JAWS): ezek tudják, mi a vezérlő neve, típusa és állapota. A hozzáférhetőségi hibák többsége abból jön, hogy a fejlesztő kikerüli ezeket: saját rajzolású „gombot” használ, kép alapú kattintható területet, vagy a vezérlőnek nem ad nevet.
Kontraszt: számoljuk ki!
A szöveg és a háttér közötti kontrasztarány 1 : 1 (azonos szín) és 21 : 1 (fekete a fehéren) között van. A WCAG ajánlása: normál szövegnél legalább 4,5 : 1, nagy szövegnél (legalább 18 pont, vagy 14 pontos félkövér) és a kezelőelemek vizuális jelzéseinél legalább 3 : 1. A számítás a színek relatív fényességén alapul:
public static class Hozzaferhetoseg
{
// egy színösszetevő (0–255) átszámítása lineáris fényességre
private static double Linearis(int ertek)
{
double s = ertek / 255.0;
return s <= 0.03928 ? s / 12.92 : Math.Pow((s + 0.055) / 1.055, 2.4);
}
// a szín relatív fényessége (0 = fekete, 1 = fehér)
public static double Fenyero(Color szin)
{
return 0.2126 * Linearis(szin.R) + 0.7152 * Linearis(szin.G) + 0.0722 * Linearis(szin.B);
}
// a két szín kontrasztaránya (1 és 21 között)
public static double Kontraszt(Color a, Color b)
{
double l1 = Fenyero(a);
double l2 = Fenyero(b);
double vilagos = Math.Max(l1, l2);
double sotet = Math.Min(l1, l2);
return (vilagos + 0.05) / (sotet + 0.05);
}
}
// használat:
double arany = Hozzaferhetoseg.Kontraszt(Color.Black, Color.White); // 21
double szurke = Hozzaferhetoseg.Kontraszt(Color.FromArgb(118, 118, 118), Color.White); // kb. 4,54| Szövegszín | Háttér | Kontraszt (kb.) | Normál szöveg (4,5) | Nagy szöveg (3) |
|---|---|---|---|---|
fekete #000000 | fehér | 21 : 1 | megfelel | megfelel |
sötétszürke #767676 | fehér | 4,54 : 1 | éppen megfelel | megfelel |
szürke #777777 | fehér | 4,48 : 1 | nem felel meg (hajszállal) | megfelel |
világosszürke #AAAAAA | fehér | 2,32 : 1 | nem felel meg | nem felel meg |
| fehér | lila #6840A5 | kb. 7,4 : 1 | megfelel | megfelel |
Enabled = false) vezérlők szövege szándékosan halvány, ezekre a küszöb nem vonatkozik. A súgószövegek, a helykitöltők és a tipp-szövegek viszont igen: ne legyenek túl halványak.Jósolj!
Egy űrlap súgószövege #999999 (világosszürke) fehér háttéren, 9 pontos betűvel. Megfelel-e a 4,5 : 1 küszöbnek, és mi a kontrasztarány nagyságrendje?
Jóslat ellenőrzése
A #999999 fehéren kb. 2,8 : 1: nem felel meg sem a normál szöveg (4,5), sem a nagy szöveg (3) küszöbének. Az ilyen szürke szöveg népszerű, mert „elegáns”, de sokaknak olvashatatlan. Sötétítsd legalább #767676 értékig.
Ne csak színnel jelezz!
A piros–zöld színtévesztő felhasználó a piros hibaszínt és a zöld „rendben” színt nem különbözteti meg. A színt soha ne használd egyedüli információhordozóként: adj mellé szöveget, jelet (ikon, szimbólum) vagy alakot:
| Rossz | Jó |
|---|---|
| A kötelező mezők pirosak. | A kötelező mezők címkéjén * jel és „(kötelező)” szöveg. |
| A hibás mező háttere piros. | Hibaikon (ErrorProvider) és hibaüzenet-szöveg a mező mellett. |
| Állapot: zöld pont = kész, piros pont = hiba. | Szöveg („Kész”, „Hiba”) vagy különböző jelek (✔, ✖) a színek mellett. |
| A grafikonon csak a színek különböztetik meg a sorokat. | Eltérő jelölők (kör, négyzet) vagy mintázat, és felirat a vonalon. |
private void Allapot(bool rendben, string uzenet)
{
// szín + jel + szöveg együtt: a szín csak erősítés
lblAllapot.Text = (rendben ? "✔ " : "✖ ") + uzenet;
lblAllapot.ForeColor = rendben ? Color.FromArgb(0, 110, 50) : Color.FromArgb(170, 20, 20); // sötét árnyalatok: jó kontraszt fehéren
}
private void btnMent_Click(object sender, EventArgs e)
{
if (txtNev.Text.Trim().Length == 0)
{
epHiba.SetError(txtNev, "A név kötelező."); // ikon + szöveg a mező mellett
Allapot(false, "A név kötelező.");
txtNev.Focus();
return;
}
epHiba.SetError(txtNev, "");
Allapot(true, "Mentve.");
}SystemSounds), mellé kell vizuális jelzés is: a hallássérült vagy a némított hangszórójú felhasználó másképp nem venné észre.Jósolj!
Egy színtévesztő felhasználó a hibás mezőt piros háttérrel látja jelölve, de a jelzés nála szürkének tűnik, ugyanolyannak, mint a többi mező. A mellette lévő ErrorProvider ikon és szöveg is hiányzik. Mit vesz észre?
Jóslat ellenőrzése
Semmit: a hibát nem érzékeli, és az űrlap „megáll”, mert a mentés nem sikerül, de ő nem tudja, miért. A hibát több csatornán kell jelezni: ikon, szöveges magyarázat és a fókusz áthelyezése a hibás mezőre (a képernyőolvasó is ezt olvassa fel).
Feliratok, AccessibleName és billentyűzet
A képernyőolvasó a vezérlőt a nevével mondja be. A név a vezérlő Text tulajdonságából jön (gomb, jelölőnégyzet), vagy a hozzá tartozó címkéből. Ha nincs ilyen (ikonos gomb, kép, a címke nélküli mező), a név hiányzik, és a felhasználó csak annyit hall: „gomb”. Három tulajdonság segít:
| Tulajdonság | Mire való? |
|---|---|
AccessibleName | A vezérlő neve a segítő eszköz számára („Mentés”, „Keresés”). |
AccessibleDescription | Hosszabb leírás („Elmenti a dokumentumot a jelenlegi fájlba”). |
AccessibleRole | A vezérlő szerepe (PushButton, Text, Link…): általában a vezérlő típusa magától megadja, csak saját rajzolású vezérlőknél kell. |
private void Form1_Load(object sender, EventArgs e)
{
// ikonos gomb: nincs szövege, ezért kell név és súgó
btnMent.AccessibleName = "Mentés";
btnMent.AccessibleDescription = "Elmenti a dokumentumot.";
ttSugo.SetToolTip(btnMent, "Mentés (Ctrl+S)"); // a látó felhasználónak
// címke nélküli keresőmező
txtKereso.AccessibleName = "Keresés a jegyzetek között";
// dekoratív kép: a képernyőolvasó kihagyhatja
pbDiszito.AccessibleRole = AccessibleRole.None;
// informatív kép: szöveges alternatíva
pbGrafikon.AccessibleName = "Az eladások havi alakulása: júniusban a legmagasabb.";
}Label, amely a tabulátorsorrendben közvetlenül a mező előtt áll (6.6 lecke): a képernyőolvasó a címkét a mező nevének tekinti. A mezőbe írt „halvány tipp” (placeholder) nem helyettesíti a címkét: eltűnik gépeléskor.ToolTip és AccessibleName. A ToolTip a látó felhasználónak, az AccessibleName a képernyőolvasónak szól: mindkettő kell.PictureBox a billentyűzettel nem érhető el, és nincs neve a képernyőolvasónak. Gombra (Button) alakítható a megjelenése (FlatStyle, kép), így az elérhetőség megmarad.Jósolj!
Egy eszköztáron három ikonos Button van (szöveg nélkül), AccessibleName nélkül, és nincs ToolTip sem. Mit hall a képernyőolvasót használó felhasználó a gombokról?
Jóslat ellenőrzése
Csak annyit, hogy „gomb” (háromszor), anélkül, hogy tudná, melyik mit csinál. A látó felhasználó az ikonról kitalálja, a képernyőolvasós nem. Két mondat kód (AccessibleName minden gombra) megoldja. A tervezőben a Properties → Accessibility csoportban is beállítható.
Magas kontrasztú mód és rendszerszínek
A Windows magas kontrasztú témái (Beállítások → Kisegítő lehetőségek → Kontrasztos témák) a rendszerszíneket (SystemColors) átállítják: sötét háttér, fényes szöveg, élénk kiemelés. A rendszerszíneket használó vezérlők ezt automatikusan követik. Ha a vezérlők színét te állítod fix értékekre (Color.WhiteSmoke, Color.FromArgb(...)), a felhasználó témája nem érvényesül, és a program olvashatatlan lehet.
// rendszerszínek használata fix színek helyett
lblCim.ForeColor = SystemColors.ControlText;
pnlSav.BackColor = SystemColors.Control;
txtMezo.BackColor = SystemColors.Window;
txtMezo.ForeColor = SystemColors.WindowText;
pnlKiemelt.BackColor = SystemColors.Highlight;
lblKiemelt.ForeColor = SystemColors.HighlightText;
// saját színek csak, ha nincs magas kontraszt
private void TemaAlkalmaz(Control szulo)
{
foreach (Control c in szulo.Controls)
{
if (c is Label && c.Tag is string cimke && cimke == "kiemelt")
{
if (SystemInformation.HighContrast)
{
c.ForeColor = SystemColors.HighlightText; // a felhasználó témája
c.BackColor = SystemColors.Highlight;
}
else
{
c.ForeColor = Color.White; // a program saját arculata
c.BackColor = Color.FromArgb(104, 64, 165);
}
}
TemaAlkalmaz(c);
}
}SystemColors osztály értékei (Control, ControlText, Window, WindowText, Highlight, HighlightText, GrayText) a felhasználó témáját követik: sötét módban is helyesek.Microsoft.Win32.SystemEvents.UserPreferenceChanged esemény figyelmeztet (a rendszerbeállítás módosult). Ezt a haladóbb lehetőséget most csak megemlítjük. Ha mégis használod, az 5.7 leckében tanultak szerint a statikus eseményről le is kell iratkoznod, amikor az ablak bezárul.Kontraszt metódussal ellenőrizhető).Jósolj!
A program címkéi mind fix Color.DimGray színűek fehér háttéren. A felhasználó magas kontrasztú (fekete hátterű) témát kapcsol be. Mit lát?
Jóslat ellenőrzése
Attól függ, mely részek követik a rendszerszíneket: az alapértelmezett vezérlők háttere feketére vált, a fix DimGray színű szöveg azonban sötétszürke marad a fekete háttéren, és gyakorlatilag olvashatatlan (a kontrasztja nagyon alacsony). Ezért ne állítsd fixre a szöveg- és háttérszíneket, ahol nem feltétlenül szükséges: az alapértelmezés (SystemColors) a témákkal együtt él.
Mit tegyél ide: ugyanaz az űrlap normál és magas kontrasztú témában, a hozzáférhető elrendezés mindkettőn olvasható.Javasolt fájlnév: winforms-6-9-kontraszt.webp · Alt szöveg: Űrlap normál és magas kontrasztú témában
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 hiba csak színnel van jelezve
txtNev.BackColor = Color.Red; // csak a háttér pirosHiba és javítás
A színtévesztő és a képernyőolvasós felhasználó nem veszi észre. Adj mellé ErrorProvider ikont és szöveges üzenetet, és tedd a fókuszt a hibás mezőre.
2. Olvashatatlan halvány szöveg
A súgószöveg világosszürke a fehér háttéren. A kontraszt 2–3 : 1 körüli, a 4,5 : 1 küszöb alatt. Sötétítsd legalább Ok és javítás
#767676 értékre, és ellenőrizd a Kontraszt metódussal.
3. Az ikonos gombnak nincs neve
A képernyőolvasó csak annyit mond: „gomb”. Hiányzik az Ok és javítás
AccessibleName és a szöveg. Adj nevet és ToolTip-et, vagy írj feliratot az ikon mellé.
4. Magas kontrasztú témában olvashatatlan a program
A felhasználó témája nem látszik, a szöveg eltűnik. A színeket fixre állítottad. Használd a Ok és javítás
SystemColors értékeit, vagy a SystemInformation.HighContrast vizsgálattal hagyd el a saját színeket.
5. A kattintható kép nem érhető el billentyűzettel
pbTorol.Click += (s, e) => Torol(); // PictureBox: nincs fókusz, nincs névHiba és javítás
A PictureBox nem kap fókuszt, és nincs neve. Használj Button vezérlőt képpel (FlatStyle = Flat, Image), amely a billentyűzettel és a képernyőolvasóval is működik.
6. A placeholder helyettesíti a címkét
A szövegmezőbe halványan „Név” szerepel, de címke nincs mellette. A helykitöltő szöveg gépeléskor eltűnik, és a segítő eszközök nem mindig olvassák. Mindig legyen látható Ok és javítás
Label a mező mellett (vagy fölött), a helykitöltő legfeljebb kiegészítés.
Mini projekt: hozzáférhetőségi ellenőrző
Készíts két részes programot: egy kontrasztszámolót és egy egyszerű űrlap-ellenőrzőt:
- Kontrasztszámoló (
tabKontrasztlap): két színválasztó gomb (btnSzoveg,btnHatter,ColorDialog), egylblMintacímke a kiválasztott szín- és háttérszínnel, egylblArany(Kontraszt: 4,54 : 1) és kétlblNormal,lblNagyjelzés a megfelelésre, színnel és jellel (✔ / ✖). AKontrasztmetódus a leckéből. - Űrlap-ellenőrző (
tabEllenorzolap): egypnlMintapanelen egy mintaűrlap szándékosan hibás elemekkel (egy címke nélküliTextBox; egy szöveg és név nélküli gomb; egy 7 pontos betűjű címke; egy rendben lévő címke–mező pár; egy világosszürke szöveg). Az Ellenőrzés gomb (btnEllenoriz) rekurzívan végigmegy apnlMintavezérlőin, és egylstJelenteslistába írja a hiányosságokat. - A szabályok: (a) beviteli mező (
TextBox,ComboBox,NumericUpDown) címke nélkül: nincsAccessibleName, és a tabulátorsorrendben előtte nemLabeláll; (b)Buttonszöveg ésAccessibleNamenélkül; (c) betűméret 9 pont alatt; (d) szövegszín–háttér kontraszt 4,5 : 1 alatt; (e) beviteli mezőnTabStop = false. - A jelentés minden sora tartalmazza a vezérlő nevét és a hiba leírását; ha nincs hiba, egy megerősítő sor (Nincs hiány.) jelenik meg. A végén összesítés: 3 hiány, 2 figyelmeztetés.
- A program maga is legyen hozzáférhető: minden vezérlőnek címke vagy
AccessibleName, a hibák ikonnal és szöveggel, rendszerszínek, logikus Tab sorrend. - Teszteld: a kontrasztszámoló ismert értékekkel (fekete/fehér = 21), az ellenőrző a mintaűrlapon, a javított mintaűrlapon (nincs hiány), a Narrator vagy a billentyűzetes használat.
Megoldás megnyitása (próbáld ki előbb önállóan!)
A címke–mező kapcsolat vizsgálata a szülő vezérlőinek TabIndex szerinti rendezésén alapul: az adott mező előtti vezérlő (a legnagyobb kisebb TabIndex a szülőn belül) legyen Label, nem üres szöveggel. A kontraszt a vezérlő ForeColor és BackColor értékéből jön (a BackColor az örökölt háttér is lehet).
private Color szovegSzin = Color.Black;
private Color hatterSzin = Color.White;
private void KontrasztFrissit()
{
lblMinta.ForeColor = szovegSzin;
lblMinta.BackColor = hatterSzin;
double arany = Hozzaferhetoseg.Kontraszt(szovegSzin, hatterSzin);
lblArany.Text = $"Kontraszt: {arany:0.00} : 1";
lblNormal.Text = (arany >= 4.5 ? "✔ " : "✖ ") + "Normál szöveg (4,5 : 1)";
lblNagy.Text = (arany >= 3.0 ? "✔ " : "✖ ") + "Nagy szöveg (3 : 1)";
}
private void btnSzoveg_Click(object sender, EventArgs e)
{
cdSzin.Color = szovegSzin;
if (cdSzin.ShowDialog() == DialogResult.OK)
{
szovegSzin = cdSzin.Color;
KontrasztFrissit();
}
}
private void btnHatter_Click(object sender, EventArgs e)
{
cdSzin.Color = hatterSzin;
if (cdSzin.ShowDialog() == DialogResult.OK)
{
hatterSzin = cdSzin.Color;
KontrasztFrissit();
}
}
private bool BeviteliMezo(Control c)
{
return c is TextBox || c is ComboBox || c is NumericUpDown;
}
private Control ElozoVezerlo(Control c)
{
Control elozo = null;
foreach (Control t in c.Parent.Controls)
{
if (t.TabIndex < c.TabIndex && (elozo == null || t.TabIndex > elozo.TabIndex))
{
elozo = t;
}
}
return elozo;
}
private Color ValosHatter(Control c)
{
Control t = c;
while (t != null && t.BackColor.A == 0)
{
t = t.Parent;
}
return t == null ? SystemColors.Control : t.BackColor;
}
private void Ellenoriz(Control szulo, List<string> hibak, List<string> figyelmeztetesek)
{
foreach (Control c in szulo.Controls)
{
if (BeviteliMezo(c))
{
Control elozo = ElozoVezerlo(c);
bool vanCimke = (elozo is Label && elozo.Text.Trim().Length > 0) || c.AccessibleName != null && c.AccessibleName.Length > 0;
if (!vanCimke)
{
hibak.Add($"{c.Name}: a beviteli mezőnek nincs címkéje vagy AccessibleName értéke.");
}
if (!c.TabStop)
{
hibak.Add($"{c.Name}: a mező kimarad a Tab sorrendből (TabStop = false).");
}
}
if (c is Button && c.Text.Trim().Length == 0 && (c.AccessibleName == null || c.AccessibleName.Length == 0))
{
hibak.Add($"{c.Name}: a gombnak nincs szövege és AccessibleName értéke.");
}
if ((c is Label || c is Button) && c.Font.Size < 9)
{
figyelmeztetesek.Add($"{c.Name}: kis betűméret ({c.Font.Size:0.#} pt).");
}
if (c is Label && c.Text.Trim().Length > 0)
{
double arany = Hozzaferhetoseg.Kontraszt(c.ForeColor, ValosHatter(c));
if (arany < 4.5)
{
figyelmeztetesek.Add($"{c.Name}: alacsony kontraszt ({arany:0.0} : 1).");
}
}
Ellenoriz(c, hibak, figyelmeztetesek);
}
}
private void btnEllenoriz_Click(object sender, EventArgs e)
{
List<string> hibak = new List<string>();
List<string> figyelmeztetesek = new List<string>();
Ellenoriz(pnlMinta, hibak, figyelmeztetesek);
lstJelentes.Items.Clear();
foreach (string h in hibak)
{
lstJelentes.Items.Add("✖ Hiba: " + h);
}
foreach (string f in figyelmeztetesek)
{
lstJelentes.Items.Add("⚠ Figyelmeztetés: " + f);
}
if (hibak.Count == 0 && figyelmeztetesek.Count == 0)
{
lstJelentes.Items.Add("✔ Nincs hiány.");
}
lblOsszegzes.Text = $"{hibak.Count} hiány, {figyelmeztetesek.Count} figyelmeztetés";
}Mit tegyél ide: az ellenőrző program: a mintaűrlap hibáinak listája (✖ és ⚠ jelekkel) és az összesítés.Javasolt fájlnév: winforms-6-9-kesz.webp · Alt szöveg: A hozzáférhetőségi ellenőrző program jelentése
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. Állapotjelző szín, jel és szöveg
Készíts állapotjelző metódust ( A színek sötét árnyalatok (a kontraszt 4,5 : 1 felett): sötétzöld, sötét borostyán, sötétvörös. Az állapotot a jel és a szöveg is hordozza, a szín csak erősít. Egy három elemű felsorolás vagy három szöveges kód elegendő az állapotokhoz.Jelez(Allapot, szöveg)), amely sikeres, figyelmeztetés és hiba állapotot mutat színnel, jellel (✔ ⚠ ✖) és szöveggel is. Milyen színeket választasz, hogy fehér háttéren elég legyen a kontraszt?Egy lehetséges megoldás
private void Jelez(string allapot, string szoveg)
{
switch (allapot)
{
case "siker":
lblAllapot.Text = "✔ " + szoveg;
lblAllapot.ForeColor = Color.FromArgb(0, 100, 40);
break;
case "figyelmeztetes":
lblAllapot.Text = "⚠ " + szoveg;
lblAllapot.ForeColor = Color.FromArgb(150, 80, 0);
break;
default:
lblAllapot.Text = "✖ " + szoveg;
lblAllapot.ForeColor = Color.FromArgb(170, 20, 20);
break;
}
}
2. Eszköztár ikonos gombokkal
Egy A gombok FlowLayoutPanelen négy ikonos gomb áll (Új, Megnyitás, Mentés, Nyomtatás). Adj mindegyiknek AccessibleName és ToolTip értéket egyetlen ciklussal. Honnan veszed a neveket?Egy lehetséges megoldás
Tag tulajdonsága tárolja a nevet (5.8 lecke), így a ciklus a Tagből dolgozik. A ToolTip kiegészítheti a gyorsbillentyűvel.private void Form1_Load(object sender, EventArgs e)
{
foreach (Control c in flpEszkoztar.Controls)
{
Button gomb = c as Button;
if (gomb != null && gomb.Tag != null)
{
gomb.AccessibleName = gomb.Tag.ToString();
ttSugo.SetToolTip(gomb, gomb.Tag.ToString());
}
}
}
3. Magas kontrasztú mód követése
A program minden címkéje és panelje a saját arculati színeket használja. Írj Az eredeti színeket a vezérlők Tema() metódust, amely magas kontrasztú módban a rendszerszíneket állítja be mindenhová (rekurzívan), és a normál módban visszaállítja a saját színeket. Hogyan tárolod az eredeti színeket?Egy lehetséges megoldás
Tag tulajdonságában sem tárolhatod (a Tag már foglalt lehet), ezért egy Dictionary<Control, Color> a megfelelő megoldás (a gyűjteményekről a 8. fejezet szól). Egyszerűbb megoldás: a saját színeket egy SajatSzinek metódus állítja be, amelyet normál módban újra hívsz.private void Tema(Control szulo)
{
foreach (Control c in szulo.Controls)
{
if (SystemInformation.HighContrast)
{
c.BackColor = SystemColors.Window;
c.ForeColor = SystemColors.WindowText;
}
else
{
SajatSzin(c); // a program arculati színei
}
Tema(c);
}
}
private void SajatSzin(Control c)
{
if (c is Label)
{
c.ForeColor = Color.FromArgb(40, 30, 50);
}
else if (c is Panel)
{
c.BackColor = Color.FromArgb(250, 248, 252);
}
}
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. Kontraszt becslése
Sorold a következő szövegszíneket fehér háttéren a kontraszt szerint csökkenően: Csökkenő sorrend: #000000, #AAAAAA, #767676, #555555. Melyek felelnek meg a 4,5 : 1 küszöbnek?Megoldás megnyitása
#000000 (21 : 1), #555555 (kb. 7,5 : 1), #767676 (4,54 : 1), #AAAAAA (2,32 : 1). Az első három megfelel, az utolsó nem.
2. Nem csak színnel
Írj három példát arra, hogyan jelezhetsz egy hibát színen kívül is egy űrlapon. (1) Hibaikon és szöveges üzenet a mező mellett (Megoldás megnyitása
ErrorProvider); (2) a hibás mezőre helyezett fókusz; (3) összefoglaló üzenet az űrlap tetején a hibák felsorolásával (és jellel, például ✖).
Közepes szint
3. A Kontraszt metódus használata
Írj kódot, amely egy A fekete és a fehér szöveg kontrasztját is kiszámoljuk a háttérhez, és a nagyobbat választjuk. Ez a „tiszta” szövegszín automatikus kiválasztása (gyakran használt trükk).TextBox szövegének és hátterének kontrasztját kiszámolja, és ha nem éri el a 4,5 : 1 arányt, a szövegszínt feketére vagy fehérre állítja (amelyik jobb kontrasztot ad).Megoldás megnyitása
private void SzovegSzinJavit(TextBox mezo)
{
if (Hozzaferhetoseg.Kontraszt(mezo.ForeColor, mezo.BackColor) >= 4.5)
{
return;
}
double fekete = Hozzaferhetoseg.Kontraszt(Color.Black, mezo.BackColor);
double feher = Hozzaferhetoseg.Kontraszt(Color.White, mezo.BackColor);
mezo.ForeColor = fekete >= feher ? Color.Black : Color.White;
}
4. AccessibleName a címke nélküli mezőn
Egy keresőmező mellett nincs címke (csak egy nagyító ikon). Mit állítasz be, hogy a mező a képernyőolvasónak érthető legyen, és mit a látó felhasználónak? A képernyőolvasónak: Megoldás megnyitása
AccessibleName = "Keresés". A látónak: egy ToolTip, és a mezőben (kiegészítésként) halvány helykitöltő szöveg. Még jobb egy látható „Keresés:” címke.txtKereso.AccessibleName = "Keresés";
txtKereso.AccessibleDescription = "Írd be a keresett szót, majd nyomd meg az Entert.";
ttSugo.SetToolTip(txtKereso, "Keresés (Ctrl+F)");
Kihívás szint
5. Betűméret-ellenőrzés
Bővítsd az ellenőrzőt úgy, hogy figyelmeztessen, ha egy beviteli mező vagy címke betűmérete 9 pont alatt van, és a vezérlő mérete rögzített ( A két feltétel együtt jelzi a veszélyt: a kis betű és a fix méret. A AutoSize = false), tehát nagyobb betűméretnél levágódhat (6.8 lecke).Megoldás megnyitása
Label.AutoSize tulajdonság elérhető, a TextBox esetén a magasságot a betű adja, ezért ott a Multiline értéket is érdemes vizsgálni.// az Ellenoriz metódusban, a címkék vizsgálatánál:
Label cimke = c as Label;
if (cimke != null && !cimke.AutoSize)
{
figyelmeztetesek.Add($"{c.Name}: fix méretű címke, nagyobb betűnél a szöveg levágódhat.");
}
6. Hozzáférhetőségi ellenőrzőlista a saját projekthez
Készíts legalább 8 pontos ellenőrzőlistát (táblázat) a saját programodhoz a lecke témáiból: kontraszt, nem csak szín, címkék, AccessibleName, billentyűzet, betűméret, magas kontraszt, üzenetek. Minden ponthoz: mit ellenőrzöl, hogyan, és mi az elvárt eredmény.Megoldás megnyitása
# Ellenőrzés Hogyan? Elvárt 1 Kontraszt Szöveg–háttér párok a Kontraszt metódussal vagy online eszközzel.Legalább 4,5 : 1 (nagy szöveg 3 : 1). 2 Nem csak színnel Szürkeárnyalatos képernyőkép. Az állapotok szürkén is megkülönböztethetők. 3 Címkék Minden beviteli mező mellett látható címke. Nincs címke nélküli mező. 4 AccessibleName Ikonos gombok, kép nélküli elemek. Mindegyiknek van neve. 5 Billentyűzet Az egész program egér nélkül. Minden elérhető, logikus Tab sorrend, nincs csapda. 6 Betűméret Windows szövegméret 150%. Nincs levágott vagy átlapolt szöveg. 7 Magas kontraszt Kontrasztos Windows-téma. A program olvasható marad. 8 Üzenetek A hibaüzenetek átolvasása. Mindegyik megmondja a hibát és a teendőt. 9 Képernyőolvasó Narrator indítása (Win+Ctrl+Enter). A vezérlők neve és típusa érthetően felolvasódik.
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. 4,5 : 1 (nagy szövegre és kezelőelemekre 3 : 1). A színtévesztő és a látássérült felhasználó nem érzékeli. Mellé kell szöveg, jel vagy alak. A vezérlő nevét adja a képernyőolvasónak, ha a vezérlőnek nincs szövege vagy címkéje (ikonos gomb, címke nélküli mező). Gépeléskor eltűnik, és a segítő eszközök nem mindig olvassák. Látható címke kell. Rendszerszíneket ( A Billentyűzet-teszt egér nélkül, szürkeárnyalatos kép, 150%-os szövegméret, kontrasztos téma, Narrator, és kontraszt-számolás.1. Mi a minimális ajánlott kontrasztarány normál szövegre?
2. Miért ne használj csak színt információhordozónak?
3. Mire való az AccessibleName?
4. Miért nem helyettesíti a placeholder a címkét?
5. Hogyan kezeled a magas kontrasztú módot?
SystemColors) használsz, vagy a SystemInformation.HighContrast vizsgálattal elhagyod a saját színeket.6. Miért jobb egy Button, mint a kattintható PictureBox?
Button kap fókuszt, billentyűzettel működtethető, és van neve a képernyőolvasónak. A PictureBox ezek egyikére sem képes.7. Milyen kis tesztekkel ellenőrizhető a hozzáférhetőség?
Mit tudsz már?
- Kiszámolod a színkontrasztot, és tudod a küszöbértékeket.
- Az információt színen kívül más csatornán is jelzed.
- Címkével,
AccessibleNameértékkel és érthető üzenetekkel segíted a képernyőolvasót. - Kezeled a magas kontrasztú módot a rendszerszínekkel.
- Egyszerű eszközökkel és teszttel ellenőrzöd a hozzáférhetőséget.
Következő lecke: mini projekt – átméretezhető űrlap
A 6. fejezet záró projektje: egy valódi, átméretezhető, billentyűzettel kezelhető és hozzáférhető űrlap a fejezet minden eszközével.




