Grafikus C# – Windows Forms tanfolyam › 7.9 lecke

Windows Forms · 7.9 lecke · betű és szín

FontDialog és ColorDialog

A betűtípus és a szín választása is kész párbeszédablakot kapott: a FontDialog és a ColorDialog. A 2.5 leckében a MiniWordben már használtad őket. Most a mélyebb tudásukat tanulod meg: a kijelölt szöveg és a teljes szöveg formázásának különbségét, az effektusokat és a színválasztást, az egyéni színek megőrzését, a betűk és színek szövegként való mentését (hogy az újraindítás után is megmaradjanak), és a választott színek kontrasztjának ellenőrzését (6.9 lecke).

  • kb. 90 perc
  • közepes szint
  • betű és szín
Diáklány C# programot készít laptopon

A lecke végére

  • használod a FontDialog tulajdonságait (Font, ShowColor, ShowEffects, ShowApply, FixedPitchOnly);
  • megkülönbözteted a kijelölés (SelectionFont) és a teljes szöveg (Font) formázását, és kezeled a vegyes formázást (null);
  • a ColorDialog egyéni színeit (CustomColors) és módjait használod;
  • a betűt és a színt szövegként mented és olvasod vissza (FontConverter, ColorTranslator);
  • a választott színek kontrasztját ellenőrzöd, és javítást javasolsz;
  • kezeled a hibákat (nem telepített betű, Font felszabadítása).

Mielőtt elkezded

Ehhez a leckéhez a 2.4–2.5 lecke (formázás, SelectionFont), a 6.9 lecke (kontraszt, Hozzaferhetoseg.Kontraszt), az 5.6 lecke (Settings) és a 7.7 lecke (using, dialógus eredménye) szükséges.

7.8 Fájl- és mappaválasztók →

FontDialog: betűtípus választása

TulajdonságJelentése
FontA kezdetben kijelölt betű, majd a választott betű (OK után).
ShowColor, ColorMegjelenik a színválasztó is; a választott szín a Color tulajdonságban.
ShowEffectsÁthúzás és aláhúzás jelölőnégyzetek (alapból igaz).
ShowApply, Apply eseményAlkalmaz gomb: a választás az ablak bezárása nélkül kipróbálható.
FixedPitchOnlyCsak egyenlő szélességű (kódhoz való) betűk.
MinSize, MaxSizeA választható betűméret határai.
FontMustExistCsak létező betű adható meg (alapból igaz).
Form1.csC#
// a kijelölt szöveg betűje (a RichTextBox-ban)
private void miBetu_Click(object sender, EventArgs e)
{
using (FontDialog ablak = new FontDialog())
{
ablak.Font = rtbSzoveg.SelectionFont ?? rtbSzoveg.Font; // vegyes kijelölésnél a SelectionFont null
ablak.ShowColor = true;
ablak.Color = rtbSzoveg.SelectionColor;
ablak.ShowEffects = true;
ablak.MinSize = 6;
ablak.MaxSize = 72;

if (ablak.ShowDialog(this) == DialogResult.OK)
{
rtbSzoveg.SelectionFont = ablak.Font; // csak a kijelölésre
rtbSzoveg.SelectionColor = ablak.Color;
}
}
}

// a teljes szöveg alapbetűje (a vezérlő Font tulajdonsága)
private void miAlapBetu_Click(object sender, EventArgs e)
{
using (FontDialog ablak = new FontDialog())
{
ablak.Font = rtbSzoveg.Font;

if (ablak.ShowDialog(this) == DialogResult.OK)
{
rtbSzoveg.Font = ablak.Font; // az egész szöveg (és az egyedi formázásokat felülírhatja)
}
}
}
SelectionFont és FontA SelectionFont a kijelölt rész betűje (kijelölés nélkül a kurzor helyén beírandó szövegé), a Font a vezérlő alapbetűje. A Font módosítása a RichTextBox-ban az egész szöveg betűtípusát átírja, ezért az egyedi formázást (félkövér szavak) elveszítheted.
?? operátorA SelectionFont ?? Font a null esetén az alapbetűt adja: vegyes formázású kijelölésnél (több betűtípus) a SelectionFont null.
Font mint értékA Font objektum megváltoztathatatlan: az ablak új példányt ad. Ha a program belül is használja, új Font példányokat hozol létre (new Font(család, méret, stílus)), és a régit felszabadíthatod, ha már senki nem használja.
Apply eseményA ShowApply = true mellett az Alkalmaz gomb a Apply eseményt váltja ki: ott kipróbálható a betű, és az ablak nyitva marad. Cancel esetén vissza kell állítani az eredetit.

Jósolj!

A szövegben két különböző betűtípusú szó van kijelölve, és a kódod a ablak.Font = rtbSzoveg.SelectionFont; értéket állítja be (a ?? nélkül). Mi történik?

Jóslat ellenőrzése

Vegyes formázású kijelölésnél a SelectionFont értéke null, és a FontDialog.Font null értékre állítása hibát (kivételt) okozhat, vagy az ablak alapértelmezett betűvel nyílik. Ezért a SelectionFont ?? rtbSzoveg.Font alak a biztonságos.

ColorDialog: szín választása

TulajdonságJelentése
ColorA kezdőszín, majd a választott szín.
AllowFullOpen, FullOpenA teljes (egyéni színes) rész engedélyezése, illetve induláskor kinyitása.
AnyColorAz összes alapszín megjelenítése.
SolidColorOnlyCsak tiszta (nem keverékes) színeket enged.
CustomColorsAz egyéni színek tömbje (int[], legfeljebb 16 elem), amelyeket a felhasználó elmentett az ablakban.
Form1.csC#
private Color SzinValaszt(Color kezdo)
{
using (ColorDialog ablak = new ColorDialog())
{
ablak.Color = kezdo;
ablak.FullOpen = true; // rögtön az egyéni színek is látszanak
ablak.CustomColors = egyeniSzinek; // az előző használatból megőrzött egyéni színek

Color eredmeny = ablak.ShowDialog(this) == DialogResult.OK ? ablak.Color : kezdo;

egyeniSzinek = ablak.CustomColors; // a felhasználó új egyéni színei megmaradnak
return eredmeny;
}
}

private int[] egyeniSzinek = new int[] { };

private void btnHatter_Click(object sender, EventArgs e)
{
pnlMinta.BackColor = SzinValaszt(pnlMinta.BackColor);
}
Mégse esetén a kezdőszínA kezdőszínnel visszatérve a hívó mindig érvényes színt kap, az if ellenőrzés nélkül is. Az egyéni színeket a Mégse után is megőrizzük (a felhasználó elmentette).
CustomColorsAz egyéni színek int értékekben vannak, a Windows COLORREF formátumában (0x00BBGGRR: a kék, zöld, piros sorrendben!). Mentéskor érdemes a számokat változatlanul tárolni, és nem átalakítani.
ÁtlátszóságA ColorDialog nem kezeli az alfa (átlátszóság) csatornát: a választott szín mindig teljesen átlátszatlan.
usingA ColorDialog és a FontDialog is Component, és kódból létrehozva using blokkal szabadítjuk fel.

Jósolj!

A színválasztó ablakban a felhasználó elment két egyéni színt, majd a Mégse gombot nyomja. A kód csak OK esetén olvassa vissza a CustomColors tulajdonságot. Mi történik az egyéni színekkel a következő megnyitáskor?

Jóslat ellenőrzése

Az új ablak nem tartalmazza az elmentett egyéni színeket (a program nem őrizte meg őket): a felhasználónak újra el kell mentenie. A CustomColors kiolvasása a Mégse után is érvényes, ezért olvassuk vissza az eredménytől függetlenül.

Betű és szín mentése szövegként

A felhasználó választását (téma, betű) érdemes megőrizni az újraindításon át (Settings, 5.6 lecke). Szövegként tárolva a beállítás hordozható és olvasható. A betűt a FontConverter, a színt a ColorTranslator alakítja:

Form1.cs (using System.ComponentModel;)C#
// Font ⇄ szöveg
private string BetuSzoveg(Font betu)
{
TypeConverter atalakito = TypeDescriptor.GetConverter(typeof(Font));

return atalakito.ConvertToInvariantString(betu); // például: Segoe UI, 12pt, style=Bold
}

private Font BetuSzovegbol(string szoveg, Font tartalek)
{
try
{
TypeConverter atalakito = TypeDescriptor.GetConverter(typeof(Font));
Font betu = (Font)atalakito.ConvertFromInvariantString(szoveg);

return betu ?? tartalek;
}
catch (Exception)
{
return tartalek; // sérült vagy nem létező betű: a tartalék
}
}

// Color ⇄ szöveg (HTML-hexa: #RRGGBB)
string hexa = ColorTranslator.ToHtml(szin); // a nevesített színeket névvel ("Red") adhatja
Color vissza = ColorTranslator.FromHtml("#6840A5");

// egyéni színek ⇄ szöveg: számok vesszővel
string egyeniSzoveg = string.Join(",", egyeniSzinek);
Invariáns szövegA ConvertToInvariantString nyelvfüggetlen formát ad (a tizedesvessző nem okoz gondot egy másik nyelvű gépen). Az olvasásnál is az Invariant változatot használd.
Hibás szövegA Settings szövege szerkeszthető fájlban van: hibás vagy hiányzó érték kivételt dobhat. Az olvasást mindig try–catch védelemmel és tartalék értékkel (tartalek) végezd.
Nem telepített betűHa a mentett betű nincs telepítve a másik gépen, a Windows helyettesítő betűt használ (vagy a konverzió hibázik). A tartalék érték megakadályozza az üres felületet.
Settings és Font típusA Settings tervező közvetlenül is felajánlja a System.Drawing.Font és Color típust, de a szöveges tárolás átláthatóbb, és a kezelése a kódban egy helyen van.

Jósolj!

A BetuSzovegbol metódus a try–catch nélkül dolgozik, és a Settings betű szövege üres (első indítás). Mi történik?

Jóslat ellenőrzése

Az üres szöveg konverziója null értéket vagy kivételt adhat, és a program összeomolhat az első indításkor (vagy üres betűvel dolgozik tovább). Az olvasás ezért mindig a tartalék érték használatával, try–catch védelemmel történjen, és az üres szöveget előbb vizsgálni kell.

A választott színek kontrasztja

Ha a felhasználó maga választ szöveg- és háttérszínt, rossz párosítást is választhat (világosszürke a fehéren). A program a 6.9 leckében megírt Hozzaferhetoseg.Kontraszt metódussal figyelmeztethet, és javaslatot adhat. Nem tiltjuk meg a választást (a felhasználó dönt), de jelezzük a következményt:

Form1.csC#
private void KontrasztFrissit()
{
double arany = Hozzaferhetoseg.Kontraszt(pnlMinta.ForeColor, pnlMinta.BackColor);

if (arany >= 4.5)
{
lblKontraszt.Text = $"✔ Kontraszt: {arany:0.0} : 1 (megfelelő)";
btnJavit.Visible = false;
}
else
{
lblKontraszt.Text = $"✖ Kontraszt: {arany:0.0} : 1 (4,5 : 1 alatt, nehezen olvasható)";
btnJavit.Visible = true; // a javítás felajánlása
}
}

// javaslat: fekete vagy fehér szöveg, amelyik jobb kontrasztot ad a háttérhez
private void btnJavit_Click(object sender, EventArgs e)
{
double fekete = Hozzaferhetoseg.Kontraszt(Color.Black, pnlMinta.BackColor);
double feher = Hozzaferhetoseg.Kontraszt(Color.White, pnlMinta.BackColor);

pnlMinta.ForeColor = fekete >= feher ? Color.Black : Color.White;
KontrasztFrissit();
}

Jósolj!

A felhasználó sárga (#FFFF00) hátteret és fehér szöveget választ. Mekkora a kontraszt nagyságrendje, és mit javasol a program?

Jóslat ellenőrzése

A fehér szöveg a sárgán nagyon gyenge: a kontraszt kb. 1,1 : 1 (a sárga is nagyon világos). A program a feketét javasolja (kb. 19 : 1). Az egymáshoz közeli világos színek (sárga–fehér) tipikusan rossz párosítások.

📷 Képernyőkép helye

Mit tegyél ide: a témaválasztó előnézete rossz kontraszttal (✖ jelzés és Javítás gomb) és a javítás után (✔).Javasolt fájlnév: winforms-7-9-kontraszt.webp · Alt szöveg: Kontraszt-figyelmeztetés a témaválasztó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 betűváltás elveszi a formázást

A betűméret módosítása után az összes félkövér szó normálissá vált.

Ok és javítás

A RichTextBox.Font átállítása az egész szöveget érinti. Kijelölt részhez használd a SelectionFont tulajdonságot, és a stílust vedd át a meglévőből (new Font(betu, stílus)).

2. NullReferenceException vegyes kijelölésnél

ablak.Font = rtbSzoveg.SelectionFont;   // null, ha a kijelölésben több betű van
Hiba és javítás

Használd a tartalék értéket: rtbSzoveg.SelectionFont ?? rtbSzoveg.Font.

3. A Mégse is megváltoztatja a színt

cd.ShowDialog();
pnlMinta.BackColor = cd.Color; // az eredmény vizsgálata nélkül
Hiba és javítás

A Cancel esetén a Color a kezdőszín marad, de a mellékhatások (folyamatban lévő módosítások) elmaradnak. Mindig vizsgáld az eredményt: if (cd.ShowDialog(this) == DialogResult.OK) { ... }.

4. Az újraindítás után az alapbetű tér vissza

A felhasználó betűválasztása nem marad meg.

Ok és javítás

Nincs mentve a Settings-be, vagy a Save() hiányzik. Tárold szövegként (FontConverter), és hívd a Save() metódust a FormClosed eseményben (5.6 lecke).

5. Összeomlás hibás szövegből

A program nem indul el, mert a Settings betű szövege sérült.

Ok és javítás

A konverzió kivételt dob. Védd try–catch blokkal, és adj tartalék értéket.

6. Olvashatatlan témát választott a felhasználó

Világos szöveg világos háttéren.

Ok és javítás

Ellenőrizd a kontrasztot a választás után (Kontraszt metódus), figyelmeztess, és ajánlj javítást. A felhasználó döntését ne tiltsd, csak jelezd a következményt.

Mini projekt: témaválasztó

Készíts programot, amelyben a felhasználó összeállítja és elmenti a saját témáját:

  1. Előnézet: egy pnlMinta panel (Dock = Fill a jobb oldalon), rajta egy lblCim (cím, a betű másfélszerese), egy lblSzoveg (többsoros minta, tördelve) és egy btnMinta mintagomb. A téma betűje és színei az előnézeten látszanak.
  2. Beállítók: Betűtípus... (FontDialog), Szövegszín..., Háttérszín..., Kiemelés színe... (a cím színe), mind ColorDialog. Az egyéni színek a program futása alatt megmaradnak (CustomColors).
  3. Kontraszt: a lblKontraszt mutatja a szöveg–háttér arányt (✔ vagy ✖, szöveggel); ✖ esetén a Javítás gomb megjelenik, és a szöveget feketére vagy fehérre állítja (6.9 lecke).
  4. Mentés: a téma (betű szövegként, három szín hexa-kóddal, az egyéni színek számai) a Settings-ben tárolódik; induláskor betöltődik, hibás vagy hiányzó érték esetén az alapértelmezett téma.
  5. Alaphelyzet gomb: visszaállítja az alapértelmezett témát (SystemColors, SystemFonts.MessageBoxFont).
  6. Az Alkalmaz a főablakra jelölőnégyzet kipipálásakor a téma az egész ablakra (rekurzívan a vezérlőkre, 5.8 lecke) is érvényesül.
  7. Teszteld: minden választó, a Mégse (nincs változás), rossz kontraszt és javítása, mentés és újraindítás, sérült beállítás (szándékosan elrontott szöveg), az egyéni színek megmaradása.
Megoldás megnyitása (próbáld ki előbb önállóan!)

A Settings-ben négy szöveges beállítás kell: TemaBetu, TemaSzoveg, TemaHatter, TemaKiemel, és egy ötödik az egyéni színeknek (TemaEgyeni). A Hozzaferhetoseg.Kontraszt metódus a 6.9 leckéből való (vedd át a projektbe).

Form1.cs (using System.ComponentModel; using System.Collections.Generic;)C#
private int[] egyeni = new int[] { };

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

private Font BetuSzovegbol(string szoveg, Font tartalek)
{
if (string.IsNullOrWhiteSpace(szoveg))
{
return tartalek;
}

try
{
TypeConverter atalakito = TypeDescriptor.GetConverter(typeof(Font));
Font betu = atalakito.ConvertFromInvariantString(szoveg) as Font;

return betu ?? tartalek;
}
catch (Exception)
{
return tartalek;
}
}

private Color SzinSzovegbol(string szoveg, Color tartalek)
{
try
{
return string.IsNullOrWhiteSpace(szoveg) ? tartalek : ColorTranslator.FromHtml(szoveg);
}
catch (Exception)
{
return tartalek;
}
}

private void Betolt()
{
Properties.Settings s = Properties.Settings.Default;

pnlMinta.Font = BetuSzovegbol(s.TemaBetu, SystemFonts.MessageBoxFont);
pnlMinta.ForeColor = SzinSzovegbol(s.TemaSzoveg, SystemColors.ControlText);
pnlMinta.BackColor = SzinSzovegbol(s.TemaHatter, SystemColors.Control);
lblCim.ForeColor = SzinSzovegbol(s.TemaKiemel, Color.FromArgb(104, 64, 165));

List<int> lista = new List<int>();

foreach (string resz in s.TemaEgyeni.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
int ertek;

if (int.TryParse(resz, out ertek))
{
lista.Add(ertek);
}
}

egyeni = lista.ToArray();
}

private void Ment()
{
Properties.Settings s = Properties.Settings.Default;

s.TemaBetu = TypeDescriptor.GetConverter(typeof(Font)).ConvertToInvariantString(pnlMinta.Font);
s.TemaSzoveg = ColorTranslator.ToHtml(pnlMinta.ForeColor);
s.TemaHatter = ColorTranslator.ToHtml(pnlMinta.BackColor);
s.TemaKiemel = ColorTranslator.ToHtml(lblCim.ForeColor);
s.TemaEgyeni = string.Join(",", egyeni);
s.Save();
}

private void Alkalmaz()
{
lblCim.Font = new Font(pnlMinta.Font.FontFamily, pnlMinta.Font.Size * 1.5f, FontStyle.Bold);
KontrasztFrissit();
}

private Color SzinValaszt(Color kezdo)
{
using (ColorDialog ablak = new ColorDialog())
{
ablak.Color = kezdo;
ablak.FullOpen = true;
ablak.CustomColors = egyeni;

Color eredmeny = ablak.ShowDialog(this) == DialogResult.OK ? ablak.Color : kezdo;
egyeni = ablak.CustomColors;

return eredmeny;
}
}

private void btnBetu_Click(object sender, EventArgs e)
{
using (FontDialog ablak = new FontDialog())
{
ablak.Font = pnlMinta.Font;
ablak.ShowEffects = false;
ablak.MinSize = 8;
ablak.MaxSize = 40;

if (ablak.ShowDialog(this) == DialogResult.OK)
{
pnlMinta.Font = ablak.Font;
Alkalmaz();
}
}
}

private void btnSzoveg_Click(object sender, EventArgs e)
{
pnlMinta.ForeColor = SzinValaszt(pnlMinta.ForeColor);
KontrasztFrissit();
}

private void btnHatter_Click(object sender, EventArgs e)
{
pnlMinta.BackColor = SzinValaszt(pnlMinta.BackColor);
KontrasztFrissit();
}

private void btnKiemel_Click(object sender, EventArgs e)
{
lblCim.ForeColor = SzinValaszt(lblCim.ForeColor);
}

private void KontrasztFrissit()
{
double arany = Hozzaferhetoseg.Kontraszt(pnlMinta.ForeColor, pnlMinta.BackColor);

lblKontraszt.Text = arany >= 4.5
? $"✔ Kontraszt: {arany:0.0} : 1 (megfelelő)"
: $"✖ Kontraszt: {arany:0.0} : 1 (4,5 : 1 alatt, nehezen olvasható)";

btnJavit.Visible = arany < 4.5;
}

private void btnJavit_Click(object sender, EventArgs e)
{
double fekete = Hozzaferhetoseg.Kontraszt(Color.Black, pnlMinta.BackColor);
double feher = Hozzaferhetoseg.Kontraszt(Color.White, pnlMinta.BackColor);

pnlMinta.ForeColor = fekete >= feher ? Color.Black : Color.White;
KontrasztFrissit();
}

private void btnAlap_Click(object sender, EventArgs e)
{
pnlMinta.Font = SystemFonts.MessageBoxFont;
pnlMinta.ForeColor = SystemColors.ControlText;
pnlMinta.BackColor = SystemColors.Control;
lblCim.ForeColor = Color.FromArgb(104, 64, 165);
Alkalmaz();
}

private void btnMent_Click(object sender, EventArgs e)
{
Ment();
tsslUzenet.Text = "A téma mentve.";
}
📷 Képernyőkép helye

Mit tegyél ide: a témaválasztó az előnézettel, a kontraszt-jelzéssel és a gombokkal.Javasolt fájlnév: winforms-7-9-kesz.webp · Alt szöveg: A témaválasztó 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. Betűstílus megtartása

A FontDialog a kijelölt szöveg betűtípusát és méretét módosítsa, de a félkövér és dőlt stílust az eredeti betűből tartsa meg. Hogyan állítod össze az új betűt?

Egy lehetséges megoldás

Az új Font a dialógus család- és méretadatával jön létre, és az eredeti Style értékét használja. (Ha a FontDialog-ban van stílusválasztás, de te csak a családot és a méretet akarod, ez a megoldás.)

Form1.csC#
Font regi = rtbSzoveg.SelectionFont ?? rtbSzoveg.Font;

using (FontDialog ablak = new FontDialog())
{
ablak.Font = regi;

if (ablak.ShowDialog(this) == DialogResult.OK)
{
rtbSzoveg.SelectionFont = new Font(ablak.Font.FontFamily, ablak.Font.Size, regi.Style);
}
}

2. Egyszerű színpaletta gombokkal

Hat gomb adja a gyakori színeket (a gomb háttere maga a szín). A hetedik gomb Egyéni... a ColorDialog-ot nyitja. Hogyan oldod meg egy közös kezelővel?

Egy lehetséges megoldás

A hat gomb közös kezelője a sender hátterét másolja (5.8 lecke), az Egyéni gomb a SzinValaszt metódust hívja.

Form1.csC#
private void Paletta_Click(object sender, EventArgs e)
{
pnlMinta.BackColor = ((Button)sender).BackColor;
}

private void btnEgyeni_Click(object sender, EventArgs e)
{
pnlMinta.BackColor = SzinValaszt(pnlMinta.BackColor);
}

3. Telepített betűk listája

Egy ComboBox a gépen telepített betűcsaládokat sorolja fel, és a kiválasztott betűvel mutatja a mintaszöveget. Honnan veszed a listát?

Egy lehetséges megoldás

A FontFamily.Families tömb tartalmazza a telepített betűcsaládokat. Nem minden család támogatja az összes stílust (a IsStyleAvailable megmondja).

Form1.csC#
private void Form1_Load(object sender, EventArgs e)
{
foreach (FontFamily csalad in FontFamily.Families)
{
if (csalad.IsStyleAvailable(FontStyle.Regular))
{
cmbBetu.Items.Add(csalad.Name);
}
}
}

private void cmbBetu_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbBetu.SelectedIndex >= 0)
{
lblMinta.Font = new Font(cmbBetu.Text, 14);
}
}

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. SelectionFont vagy Font?

Melyiket állítod: (a) egy szó betűjét; (b) a teljes dokumentum alapbetűjét?

Megoldás megnyitása

(a) SelectionFont (kijelölés után); (b) Font (a vezérlő tulajdonsága), tudva, hogy az egyedi formázást felülírhatja.

2. Szín hexa kóddal

Írd át a Color.FromArgb(104, 64, 165) színt hexa szövegre és vissza.

Megoldás megnyitása

ColorTranslator.ToHtml(Color.FromArgb(104, 64, 165)) a #6840A5 szöveget adja; vissza a ColorTranslator.FromHtml("#6840A5").

Közepes szint

3. Szín és betű a kijelölésre

A FontDialog ShowColor tulajdonságával a kijelölt szöveg betűje és színe egyszerre állítható. Mire kell figyelni a Color tulajdonság kezdőértékénél?

Megoldás megnyitása

A Color kezdőértéke legyen a kijelölés jelenlegi színe (SelectionColor), különben a dialógus feketével nyílik, és OK-ra a szín feketére váltana, akkor is, ha a felhasználó csak a betűt akarta módosítani.

4. Kijelölés színe a vegyes szövegben

Mit ad a SelectionColor vegyes színű kijelölésnél?

Megoldás megnyitása

Vegyes színű kijelölésnél a SelectionColor értéke Color.Empty lehet (üres szín): ezt a IsEmpty tulajdonsággal ellenőrizd, és szükség esetén használd az alapszínt.

Form1.csC#
Color kezdo = rtbSzoveg.SelectionColor.IsEmpty ? rtbSzoveg.ForeColor : rtbSzoveg.SelectionColor;

Kihívás szint

5. Legutóbbi színek listája

Egy FlowLayoutPanel az utoljára választott 8 szín kis négyzeteit mutatja, rájuk kattintva a szín újra választható. Hogyan építed?

Megoldás megnyitása

Egy List<Color> tárolja az utolsó 8 színt (újabb elöl, ismétlés nélkül), és minden választás után újraépíti a négyzeteket (dinamikus vezérlők, 6.4 lecke).

Form1.csC#
private readonly List<Color> legutobbi = new List<Color>();

private void Megjegyez(Color szin)
{
legutobbi.Remove(szin);
legutobbi.Insert(0, szin);

while (legutobbi.Count > 8)
{
legutobbi.RemoveAt(legutobbi.Count - 1);
}

for (int i = flpSzinek.Controls.Count - 1; i >= 0; i--)
{
Control c = flpSzinek.Controls[i];
c.Click -= Negyzet_Click;
flpSzinek.Controls.RemoveAt(i);
c.Dispose();
}

foreach (Color s in legutobbi)
{
Panel negyzet = new Panel { Size = new Size(24, 24), BackColor = s, BorderStyle = BorderStyle.FixedSingle, Margin = new Padding(3) };
negyzet.Click += Negyzet_Click;
flpSzinek.Controls.Add(negyzet);
}
}

private void Negyzet_Click(object sender, EventArgs e)
{
pnlMinta.BackColor = ((Panel)sender).BackColor;
}

6. Betűméret csak a megengedett tartományban

A felhasználó nem választhat 8 pontnál kisebb és 24 pontnál nagyobb betűméretet (hozzáférhetőség, 6.9 lecke). Hogyan szabod meg a dialógusban, és mit teszel, ha a mentett érték kívül esik?

Megoldás megnyitása

A MinSize és MaxSize tulajdonság korlátozza a választást. Mentett értéknél (kézzel szerkesztett beállítás) is ellenőrizni kell: a tartományon kívüli értéket a legközelebbi határra igazítod.

Form1.csC#
ablak.MinSize = 8;
ablak.MaxSize = 24;

// betöltéskor:
float meret = Math.Max(8f, Math.Min(24f, betu.Size));
betu = new Font(betu.FontFamily, meret, betu.Style);

Gyors önellenőrzés

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

1. Mi a különbség a SelectionFont és a Font között?

A SelectionFont a kijelölt rész betűje (vegyes kijelölésnél null), a Font a vezérlő alapbetűje (az egész szöveget érinti).

2. Mire való a ShowColor?

A FontDialog mellé színválasztót is ad (Color tulajdonság).

3. Mi a CustomColors?

A ColorDialog egyéni színeinek tömbje (int[], legfeljebb 16): érdemes megőrizni a használatok között.

4. Hogyan mentesz betűt szövegként?

TypeDescriptor.GetConverter(typeof(Font)).ConvertToInvariantString(betu), olvasásnál ConvertFromInvariantString, try–catch védelemmel.

5. Hogyan alakítasz színt hexa szöveggé?

ColorTranslator.ToHtml és ColorTranslator.FromHtml.

6. Miért ellenőrizd a választott színek kontrasztját?

Mert a felhasználó olvashatatlan párosítást is választhat. Figyelmeztetsz és javítást ajánlasz, de nem tiltasz.

7. Mit tegyél a ShowDialog eredményével?

Csak OK esetén alkalmazd a választást; a Cancel a felhasználó szándékos döntése (nincs változás).

Mit tudsz már?

  • Használod a FontDialog és ColorDialog beállításait.
  • Megkülönbözteted a kijelölés és a teljes szöveg formázását.
  • Betűt és színt szövegként mentesz és olvasol vissza, hibatűrően.
  • A választott színek kontrasztját ellenőrzöd, és javítást ajánlasz.
  • Megőrzöd az egyéni színeket, és kezeled a gyakori hibákat.

Következő lecke: mini projekt – beállítóablak több Formmal

A 7. fejezet záró projektje: egy valódi alkalmazás beállítóablakkal, névjegy ablakkal, menüvel, állapotsorral és helyi menüvel.