Grafikus C# – Windows Forms tanfolyam › 2.4 lecke

Windows Forms · 2.4 lecke

Kijelölt szöveg formázása – félkövér, dőlt, aláhúzott

Egy igazi szövegszerkesztőben kijelölsz egy szót, és egy gombbal félkövérré teszed. Ebben a leckében a MiniWord is megtanulja ezt. Megismerjük a kijelölést, a Font objektumot, és egy ügyes trükköt, amellyel egyetlen gomb be- és kikapcsolja a formázást.

  • kb. 60–75 perc
  • kezdő szint
  • szövegformázás
Diák C# programozást gyakorol egy tanulósarokban

A lecke végére

  • érted, mit jelent a kijelölés a RichTextBoxban (SelectionFont, SelectedText);
  • tudod, hogy a Font objektum nem módosítható, ezért újat kell létrehozni;
  • érted a FontStyle értékeket és a ^ (XOR) műveletet;
  • egy gombbal be- és kikapcsolod a félkövér, dőlt és aláhúzott formázást;
  • kezeled, ha a kijelölésben vegyes a formázás (null);
  • elintézed, hogy a kijelölés a gombnyomás után is látszódjon.

Mielőtt elkezded

Ehhez a leckéhez kell a MiniWord projekt a 2.3 lecke után. Az if–else és a null értelmezése is hasznos: a null azt jelenti, hogy „nincs érték”.

2.3 SaveFileDialog – mentés →

Mit jelent a kijelölés?

A formázás mindig a kijelölt szövegre vonatkozik, ezért először ezt kell megértenünk. A RichTextBox néhány tulajdonsága a kijelölésről tájékoztat:

SelectedTextA kijelölt szöveg. Ha nincs kijelölés, üres szöveg.
SelectionStartA kijelölés első karakterének sorszáma. A számozás 0-tól indul.
SelectionLengthA kijelölt karakterek száma.
SelectionFontA kijelölt szöveg betűtípusa, mérete és stílusa. Ezt fogjuk állítani.

Ha nincs kijelölés, a kurzor helyén áll a beszúrási pont. Ilyenkor a formázás a következő begépelt karakterekre vonatkozik, ahogy a Wordben is.

Te jössz!

Tegyél az ablakra egy btnKijeloles nevű gombot. Írd meg hozzá a Click eseményt, amely egy üzenetablakban megmutatja a kijelölt szöveget és a hosszát. Jelölj ki a szövegdobozban egy szót, és próbáld ki.

Egy lehetséges megoldás
private void btnKijeloles_Click(object sender, EventArgs e)
{
MessageBox.Show($"Kijelölt szöveg: {rtbDokumentum.SelectedText}, hossza: {rtbDokumentum.SelectionLength}");
}

A gombra kattintás után a kijelölés valószínűleg eltűnik a szemed elől. Ez nem hiba, az 5. szakaszban megmagyarázzuk és kijavítjuk.

A Font objektum nem módosítható

A betűtípus adatait egy Font objektum tárolja: a betűcsaládot (például Arial), a méretet és a stílust. A SelectionFont ilyen objektumot ad vissza. Van azonban egy szabály: a már elkészült Font objektum nem módosítható. Nem írhatod át benne a stílust, helyette újat kell létrehozni, és azt kell beállítani.

Olyan ez, mint egy kinyomtatott kártya. Nem javítod át a betűit, hanem új kártyát nyomtatsz.

Form1.csC#
Font regi = rtbDokumentum.SelectionFont;
rtbDokumentum.SelectionFont = new Font(regi, FontStyle.Bold);
Font regiAz aktuális betűtípus, amelyet elmentünk egy változóba.
new Font(regi, FontStyle.Bold)Új Font: ugyanaz a betűcsalád és méret, mint a régié, de a stílusa félkövér.

Kapcsolók: a FontStyle és a ^ művelet

A fenti kód félkövérre állít, de a dőlt vagy aláhúzott formázást elvenné. Mi azt szeretnénk, hogy a stílusok kombinálhatók legyenek, és ugyanaz a gomb ki is kapcsolja a formázást.

A FontStyle olyan, mint egy sor kapcsoló. Mindegyik stílus külön kapcsoló:

Regular = 0Nincs bekapcsolva egyik sem.
Bold = 1Félkövér.
Italic = 2Dőlt.
Underline = 4Aláhúzott.

Az értékek azért 1, 2 és 4, mert így mindegyik stílus a számnak egy külön bitje, és összeadva sem keverednek össze. A félkövér és dőlt együtt például 1 + 2 = 3.

A ^ jel (XOR, kizáró vagy) úgy működik, mint egy fordító kapcsoló: átbillenti a megadott stílust, a többit érintetlenül hagyja.

Hogyan billent át a ^?C#
// félkövér (1) ^ félkövér (1) = 0 → a félkövér kikapcsol
FontStyle.Regular // 0

// normál (0) ^ félkövér (1) = 1 → bekapcsol
FontStyle.Bold // 1

// félkövér és dőlt (3) ^ félkövér (1) = 2 → csak a dőlt marad
FontStyle.Italic // 2

Jósolj!

Egy szó dőlt (2). Megnyomod a félkövér gombot, amely a ^ FontStyle.Bold műveletet végzi. Mi lesz a szó formázása? És ha még egyszer megnyomod?

Jóslat ellenőrzése

Először: 2 ^ 1 = 3, vagyis a szó félkövér és dőlt lesz. Másodszor: 3 ^ 1 = 2, vagyis a félkövér kikapcsol, a dőlt megmarad. Ez pontosan a Word B gombjának viselkedése.

A kód: egy metódus, három gomb

Tegyél a RichTextBox fölé három gombot, és állítsd be a tulajdonságaikat:

btnFelkoverText: F
A Font tulajdonságában állítsd félkövérre.
btnDoltText: D
A Font tulajdonságában állítsd dőltre.
btnAlahuzottText: A
A Font tulajdonságában állítsd aláhúzottra.
Miért F, D, A?A magyar Wordben is ezek a betűk jelölik a félkövér, dőlt és aláhúzott gombot.
📷 Képernyőkép helye

Mit tegyél ide: a MiniWord a három formázó gombbal. A RichTextBox fölött az F (félkövér), a D (dőlt) és az A (aláhúzott) gomb látszik, a szövegdobozban egy kijelölt szóval. Mellette a Properties ablak is megmutathatja a gomb Font tulajdonságát.Javasolt fájlnév: winforms-2-4-formazo-gombok.webp · Alt szöveg: A MiniWord három formázó gombbal: félkövér, dőlt és aláhúzott

Mindhárom gomb ugyanazt csinálja, csak más stílussal. Ezért nem írjuk meg háromszor a kódot, hanem egyetlen saját metódusba tesszük, amelynek bemenete is van. A zárójelben álló FontStyle stilus azt jelenti, hogy a metódus meghívásakor meg kell mondani, melyik stílust kapcsolja át.

Form1.csC#
private void btnFelkover_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Bold);
}

private void btnDolt_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Italic);
}

private void btnAlahuzott_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Underline);
}

private void StilusValt(FontStyle stilus)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi != null)
{
rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ stilus);
}
else
{
MessageBox.Show("A kijelölésben többféle formázás van. Jelölj ki egységes szövegrészt!");
}

rtbDokumentum.Focus();
}
StilusValt(FontStyle stilus)Saját metódus, amelynek egy bemenete van: az átkapcsolandó stílus.
regi != nullAkkor igaz, ha a kijelölésnek egységes a formázása, tehát van aktuális Font.
regi.Style ^ stilusÁtbillenti a kért stílust, a többit megtartja.
rtbDokumentum.Focus()Visszaadja a kurzort a szövegdoboznak, hogy a felhasználó gépelhessen tovább.

Mikor null a SelectionFont?

Ha a kijelölésben többféle betűtípus, méret vagy stílus keveredik, a RichTextBox nem tud egyetlen Font-ot visszaadni, ezért null az értéke. Ha ezt nem ellenőrzöd, és használod a regi.Style tulajdonságot, a program összeomlik. Ezért van a kódban az if. Az újabb .NET projektekben a Font regi = ... sor alatt zöld hullámvonal is jelezheti ugyanezt (CS8600). Ez figyelmeztetés, nem hiba. Ha eltüntetnéd, írj Font? regi típust, de csak az újabb .NET projektben (lásd a 0.4 leckét).

Hova tűnt a kijelölés?

Kipróbáltad már a programot? Észrevehetted, hogy a gombra kattintva a kijelölt szó kékes háttere eltűnik. A formázás ettől még megtörténik, de nem látszik, melyik szöveget formáztad. Ennek az az oka, hogy a gombra kattintva a fókusz átkerül a szövegdobozról a gombra, a RichTextBox pedig alapból elrejti a kijelölést, ha nincs rajta a fókusz.

A megoldás: HideSelection

Jelöld ki a RichTextBoxot, és a Properties ablakban állítsd a HideSelection tulajdonságot False-ra. Így a kijelölés akkor is látszik, ha a fókusz éppen egy gombon áll. A kódban az rtbDokumentum.Focus() sor pedig a formázás után visszaadja a kurzort a szövegdoboznak.

📷 Képernyőkép helye

Mit tegyél ide: a Properties ablak, amelyben a RichTextBox HideSelection tulajdonsága False értékre van állítva. Mellette vagy külön képen a futó MiniWord, a kijelölt szóval, miközben az egérkurzor a formázó gombokon áll.Javasolt fájlnév: winforms-2-4-hideselection.webp · Alt szöveg: A RichTextBox HideSelection tulajdonsága hamisra állítva a Visual Studio Properties ablakában

Jósolj, aztán futtasd!

Minden feladatnál először írd le, mit vársz, és csak utána próbáld ki.

1. Oda-vissza

Kijelölsz egy szót, és kétszer megnyomod az F gombot. Mi történik?

Jóslat ellenőrzése

Az első kattintásra félkövér lesz (0 ^ 1 = 1), a másodikra visszaáll normálra (1 ^ 1 = 0).

2. Két stílus egyszerre

Kijelölsz egy szót, majd megnyomod az F, utána a D gombot. Mindkét stílus megmarad?

Jóslat ellenőrzése

Igen: 1 ^ 2 = 3. A szó félkövér és dőlt lesz. Mivel a regi.Style alapján számolunk, a korábbi stílus sosem vész el.

3. Vegyes kijelölés

Az egyik szót félkövérre formázod, a mellette lévőt nem. Kijelölöd mindkettőt, és megnyomod az F gombot. Mi történik?

Jóslat ellenőrzése

A kijelölésben két különböző formázás van, ezért a SelectionFont értéke null. A program az üzenetet mutatja. Jelölj ki egységesen formázott részt, és működni fog.

4. Mentés és újranyitás

Formázol két szót, mented a dokumentumot, majd újra megnyitod. Megmarad a formázás?

Jóslat ellenőrzése

Igen, mert a 2.3 leckében RTF típussal mentettünk. Ha a fájlt a Wordben is megnyitod, ott is látszani fog.

Hibakeresés: te vagy a hibadetektív

Hibavadászat

Jósold meg, hogy fordítási hiba, futás közbeni hiba vagy rossz működés lesz-e. Csak utána nyisd le a megoldást.

1. Eltűnik a korábbi stílus

// btnDolt_Click
rtbDokumentum.SelectionFont = new Font(regi, FontStyle.Italic);
Hiba és javítás

Rossz működés: a dőlt gomb mindig csak dőltet állít, ezért a korábbi félkövér elvész. Javítás: regi.Style ^ FontStyle.Italic, így a többi stílus megmarad.

2. Nem módosítható

rtbDokumentum.SelectionFont.Style = FontStyle.Bold;
// CS0200: Property or indexer 'Font.Style' cannot be assigned to -- it is read only
Hiba és javítás

Fordítási hiba (CS0200): a Font objektum csak olvasható. Nem a meglévő objektum stílusát módosítjuk, hanem új Font-ot készítünk: new Font(regi, FontStyle.Bold).

3. Összeomlik a vegyes kijelölésnél

Font regi = rtbDokumentum.SelectionFont;
rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ stilus);
Hiba és javítás

Futás közbeni hiba (NullReferenceException), ha a kijelölésben többféle formázás van, mert a regi értéke null. Javítás: az if (regi != null) ellenőrzés.

4. Az F csak bekapcsol, kikapcsolni nem tud

rtbDokumentum.SelectionFont = new Font(regi, regi.Style | FontStyle.Bold);
Hiba és javítás

Rossz működés: a | (vagy) összekapcsolja a stílusokat, de nem billent át. Ha a félkövér már be van kapcsolva, a 1 | 1 megint 1, tehát soha nem lehet kikapcsolni. A kapcsolóhoz ^ kell.

5. Nem látom, mit formáztam

A formázás működik, de a gombra kattintva a kijelölt szöveg háttere eltűnik.

Hiba és javítás

A RichTextBox alapból elrejti a kijelölést, ha elveszíti a fókuszt. Állítsd a HideSelection tulajdonságot False-ra, és a metódus végén hívd meg a rtbDokumentum.Focus() metódust.

Mini projekt: a MiniWord formáz

Add hozzá a három formázó gombot a MiniWordhöz. A Megnyitás, a Mentés és a számláló kódja változatlan marad, a következőket kell beírnod. Először próbáld meg önállóan megírni, és csak utána nyisd meg a megoldást.

Megoldás és ellenőrzés megnyitása
Form1.cs – új részekC#
private void btnFelkover_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Bold);
}

private void btnDolt_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Italic);
}

private void btnAlahuzott_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Underline);
}

private void StilusValt(FontStyle stilus)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi != null)
{
rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ stilus);
}
else
{
MessageBox.Show("A kijelölésben többféle formázás van. Jelölj ki egységes szövegrészt!");
}

rtbDokumentum.Focus();
}

Ne felejtsd el a RichTextBox HideSelection tulajdonságát False-ra állítani.

📷 Képernyőkép helye

Mit tegyél ide: a MiniWord egy rövid szöveggel, amelyben van félkövér, dőlt és aláhúzott szó, és egy olyan is, amelyik több stílust kombinál (például félkövér és dőlt).Javasolt fájlnév: winforms-2-4-miniword-formazva.webp · Alt szöveg: A MiniWord formázott szöveggel: félkövér, dőlt és aláhúzott szavak

Az újranyitási teszt: formázz meg néhány szót, mentsd el a dokumentumot, zárd be a programot, majd nyisd meg újra ugyanazt a fájlt. A formázásnak meg kell maradnia.

Önálló gyakorlófeladatok

Először készíts saját megoldást. A lenyitható rész csak ellenőrzéshez van.

1. Áthúzott szöveg

Készíts egy btnAthuzott gombot, amely áthúzottra állítja a kijelölt szöveget.

Egy lehetséges megoldás
private void btnAthuzott_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Strikeout);
}

A FontStyle.Strikeout értéke 8, tehát a már ismert kapcsolók közé egy újabb kerül.

2. Piros szín

Készíts egy btnPiros gombot, amely a kijelölt szöveg színét pirosra állítja.

Egy lehetséges megoldás
private void btnPiros_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectionColor = Color.Red;
rtbDokumentum.Focus();
}

A SelectionColor a kijelölt szöveg színét állítja. Ha a Color alá hullámvonal kerül, add a fájl elejéhez a using System.Drawing; sort.

3. Alaphelyzet gomb

Készíts egy btnAlaphelyzet gombot, amely a kijelölt szöveg formázását visszaállítja a szövegdoboz alapértelmezett betűtípusára.

Egy lehetséges megoldás
private void btnAlaphelyzet_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectionFont = rtbDokumentum.Font;
rtbDokumentum.Focus();
}

A rtbDokumentum.Font a teljes szövegdoboz alap betűtípusa. Ezt adjuk oda a kijelölésnek, így a félkövér, dőlt és aláhúzott formázás megszűnik, és a méret is visszaáll.

Gyakorlótár: 6 további feladat

Három szinten gyakorolhatsz: alap, közepes és kihívás. A feladatokhoz egy rtbDokumentum RichTextBox és a leírt gombok kellenek. Csak a próbálkozás után nyisd le a megoldást.

Alap szint

1. Dőlt gomb

A btnDolt gomb kapcsolja a dőlt stílust a kijelölt szövegen: ha dőlt, legyen normál, ha nem dőlt, legyen dőlt. A többi stílus maradjon meg.

Megoldás megnyitása

A ^ (kizáró vagy) kapcsoló: ha a stílus be van kapcsolva, kikapcsolja, ha ki van kapcsolva, bekapcsolja. A SelectionFont null lehet vegyes kijelölésnél, ezért ellenőrizzük.

Form1.csC#
private void btnDolt_Click(object sender, EventArgs e)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi == null)
{
MessageBox.Show("A kijelölésben többféle formázás van.");
return;
}

rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ FontStyle.Italic);
rtbDokumentum.Focus();
}

2. Közös metódus a három stílushoz

Írj egy StilusValt(FontStyle stilus) metódust, és kösd hozzá a btnFelkover, btnDolt és btnAlahuzott gombot.

Megoldás megnyitása

A metódus paramétere a kapcsolandó stílus: FontStyle.Bold, FontStyle.Italic vagy FontStyle.Underline. Így a kód nem ismétlődik háromszor.

Form1.csC#
private void StilusValt(FontStyle stilus)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi == null)
{
MessageBox.Show("A kijelölésben többféle formázás van.");
return;
}

rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ stilus);
rtbDokumentum.Focus();
}

private void btnFelkover_Click(object sender, EventArgs e) { StilusValt(FontStyle.Bold); }
private void btnDolt_Click(object sender, EventArgs e) { StilusValt(FontStyle.Italic); }
private void btnAlahuzott_Click(object sender, EventArgs e) { StilusValt(FontStyle.Underline); }

Közepes szint

3. Nincs kijelölt szöveg

Ha nincs kijelölve szöveg, a gomb jelezze: Előbb jelölj ki szöveget!, és ne változtasson semmit.

Megoldás megnyitása

A SelectionLength a kijelölt karakterek száma. Ha nulla, nincs kijelölés. Megjegyzés: ilyenkor a stílus a kurzortól beírt új szövegre is beállítható, ezért ez a viselkedés a szerkesztő tervezési döntése.

Form1.csC#
private void StilusValt(FontStyle stilus)
{
if (rtbDokumentum.SelectionLength == 0)
{
MessageBox.Show("Előbb jelölj ki szöveget!");
return;
}

Font regi = rtbDokumentum.SelectionFont;

if (regi == null)
{
MessageBox.Show("A kijelölésben többféle formázás van.");
return;
}

rtbDokumentum.SelectionFont = new Font(regi, regi.Style ^ stilus);
rtbDokumentum.Focus();
}

4. Áthúzott stílus

Készíts egy btnAthuzott gombot, amely az áthúzott stílust kapcsolja.

Megoldás megnyitása

Az áthúzott stílus neve FontStyle.Strikeout. A StilusValt metódus bármelyik stílussal működik.

Form1.csC#
private void btnAthuzott_Click(object sender, EventArgs e)
{
StilusValt(FontStyle.Strikeout);
}

Kihívás szint

5. Formázás törlése

A btnNormal gomb vegye le a kijelölt szövegről az összes stílust (félkövér, dőlt, aláhúzott, áthúzott), és állítsa a betűszínt feketére. A betűtípus és a méret maradjon.

Megoldás megnyitása

A FontStyle.Regular a stílus nélküli állapot. Az új Font a régi családot és méretet megtartja, csak a stílus változik.

Form1.csC#
private void btnNormal_Click(object sender, EventArgs e)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi != null)
{
rtbDokumentum.SelectionFont = new Font(regi, FontStyle.Regular);
}

rtbDokumentum.SelectionColor = Color.Black;
rtbDokumentum.Focus();
}

6. Címsor gomb

A btnCimsor gomb a kijelölt szöveget félkövér és aláhúzott stílusúra állítsa egyszerre, a többi jellemzőt megtartva.

Megoldás megnyitása

Több stílus együtt a | (vagy) jellel kapcsolható össze. Ez beállítja a megadott stílusokat, a régieket felülírja (nem kapcsolgat), ezért az eredmény mindig ugyanaz.

Form1.csC#
private void btnCimsor_Click(object sender, EventArgs e)
{
Font regi = rtbDokumentum.SelectionFont;

if (regi == null)
{
return;
}

rtbDokumentum.SelectionFont = new Font(regi, FontStyle.Bold | FontStyle.Underline);
rtbDokumentum.Focus();
}

Gyors önellenőrzés

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

1. Mire vonatkozik a SelectionFont?

A kijelölt szövegre. Ha nincs kijelölés, a kurzortól kezdve begépelt szövegre.

2. Miért kell új Font objektumot létrehozni?

Mert a Font objektum nem módosítható. A stílus átállításához új objektumot kell készíteni, és azt beállítani a SelectionFont-nak.

3. Mit csinál a ^ jel a FontStyle értékeknél?

Átbillenti a megadott stílust: ha be volt kapcsolva, kikapcsolja, ha ki volt kapcsolva, bekapcsolja. A többi stílust nem változtatja meg.

4. Mikor null a SelectionFont?

Ha a kijelölésben többféle betűtípus, méret vagy stílus keveredik, mert ilyenkor nincs egyetlen Font, amelyet vissza lehetne adni.

5. Mire való a HideSelection tulajdonság?

Azt szabályozza, hogy a RichTextBox elrejtse-e a kijelölést, ha nincs rajta a fókusz. False értéknél a kijelölés akkor is látszik.

6. Miért tettük a kódot a StilusValt metódusba?

Mert mindhárom gomb ugyanazt csinálja, csak a stílus más. Így a kódot egyszer kell megírni, és a stílust bemenetként adjuk át.

Mit tudsz már?

  • Érted a kijelölést és a SelectionFont szerepét.
  • Tudod, hogy a Font objektum nem módosítható, ezért újat készítesz.
  • Érted a FontStyle kapcsolókat és a ^ műveletet.
  • Egy gombbal be- és kikapcsolod a félkövér, dőlt és aláhúzott formázást.
  • Kezeled a vegyes kijelölést (null).
  • A HideSelection beállításával látszik a kijelölés.

Következő lecke: betűméret és betűtípus

A formázó gombok már működnek. A következő leckében legördülő listákkal választhatunk betűtípust és betűméretet.