Grafikus C# – Windows Forms tanfolyam › 2.12 lecke

Windows Forms · 2.12 lecke

Undo, Redo, Copy, Cut és Paste – a szerkesztés alapműveletei

Egy szövegszerkesztő nem létezhet visszavonás, másolás és beillesztés nélkül. A jó hír: a RichTextBox mindezt már tudja, és a Ctrl+Z, Ctrl+C, Ctrl+V billentyűk is működnek benne. Ebben a leckében egy Szerkesztés menüt készítünk hozzá, amely a megfelelő pillanatban csak azokat a menüpontokat engedi, amelyeknek van értelme.

  • kb. 60 perc
  • kezdő–közepes szint
  • szerkesztés
Anime stílusú fiú és lány egy C# programozási feladatot beszél meg

A lecke végére

  • a RichTextBox beépített műveleteit hívod meg (Undo, Redo, Cut, Copy, Paste, SelectAll);
  • Szerkesztés menüt építesz ezekhez;
  • a menüpontokat a CanUndo, CanRedo és SelectionLength alapján engeded vagy tiltod;
  • a DropDownOpening eseményt használod a menüpontok állapotának frissítésére;
  • sima szövegként illeszted be a másolt tartalmat;
  • a ClearUndo() segítségével megakadályozod, hogy a megnyitás visszavonható legyen.

Mielőtt elkezded

Ehhez a leckéhez kell a MiniWord a 2.11 lecke után, valamint a menüépítés (1.7 lecke).

2.11 Kijelölés és SelectionChanged →

A RichTextBox már tudja

A RichTextBox minden alapvető szerkesztő műveletet kínál metódusként. A billentyűkombinációk (Ctrl+Z, Ctrl+Y, Ctrl+X, Ctrl+C, Ctrl+V, Ctrl+A) mindenféle kód nélkül működnek benne:

MűveletMetódusBillentyű
VisszavonásUndo()Ctrl+Z
Újra (visszavonás visszavonása)Redo()Ctrl+Y
KivágásCut()Ctrl+X
MásolásCopy()Ctrl+C
BeillesztésPaste()Ctrl+V
Mindent kijelölSelectAll()Ctrl+A

Két tulajdonság is segít: a CanUndo és a CanRedo igaz/hamis értéke megmondja, van-e mit visszavonni, illetve újra végrehajtani.

Jósolj!

Frissen elindítottad a MiniWordöt, még semmit nem gépeltél. Mi a CanUndo értéke? Beírsz egy szót. Mi lesz az értéke? Visszavonod, mi lesz a CanRedo értéke?

Jóslat ellenőrzése

Induláskor a CanUndo hamis (nincs mit visszavonni). Gépelés után igaz. A visszavonás után a CanRedo igazra vált, mert a visszavont gépelést újra végre lehet hajtani.

A menüpontok állapota: csak azt engedd, ami értelmes

Szürkén jelenik meg a Visszavonás, ha nincs mit visszavonni, és szürke a Kivágás és a Másolás, ha nincs kijelölt szöveg. Ezt a menüpontok Enabled tulajdonságával érheted el. De mikor állítsd be? A kényelmes pillanat az, amikor a felhasználó megnyitja a menüt. Erre való a főmenü DropDownOpening eseménye:

Form1.csC#
private void miSzerkesztes_DropDownOpening(object sender, EventArgs e)
{
miVisszavon.Enabled = rtbDokumentum.CanUndo;
miUjra.Enabled = rtbDokumentum.CanRedo;

bool vanKijeloles = rtbDokumentum.SelectionLength > 0;
miKivag.Enabled = vanKijeloles;
miMasol.Enabled = vanKijeloles;
}
DropDownOpeningA menü lenyitása előtt fut le. Itt még frissíthetők a menüpontok.
miVisszavon.Enabled = CanUndoA menüpont akkor használható, ha van mit visszavonni.
bool vanKijelolesEgy igaz/hamis változó: a kijelölés hossza nagyobb-e nullánál. Kétszer használjuk, ezért érdemes változóba tenni.
Miért nem a SelectionChanged?Az minden kurzormozgásnál lefut. A menü megnyitásakor elég egyszer frissíteni.

Jósolj!

Kijelölsz egy szót, megnyitod a Szerkesztés menüt: engedélyezett a Másolás? Utána a menü megnyitása nélkül nyomsz egy nyílbillentyűt (a kijelölés megszűnik). Mi a Másolás állapota a következő megnyitáskor?

Jóslat ellenőrzése

Az első megnyitáskor engedélyezett. A nyílbillentyű megszünteti a kijelölést, ezért a következő megnyitáskor a DropDownOpening újra lefut, a SelectionLength nulla, és a Másolás szürke lesz.

📷 Képernyőkép helye

Mit tegyél ide: a lenyitott Szerkesztés menü kijelölés nélkül: a Visszavonás, Kivágás és Másolás menüpont szürke, a Beillesztés és Mindent kijelöl használható.Javasolt fájlnév: winforms-2-12-szurke-menupontok.webp · Alt szöveg: A Szerkesztés menü letiltott menüpontokkal kijelölés nélkül

Sima szöveg beillesztése és a visszavonás törlése

Ha Wordből vagy weboldalról másolsz be szöveget, a Paste() a formázást (betűtípust, színeket) is beilleszti. Ha csak a sima szöveget szeretnéd, a Paste metódusnak megadhatod a formátumot:

Form1.csC#
private void miSimaBeillesztes_Click(object sender, EventArgs e)
{
rtbDokumentum.Paste(DataFormats.GetFormat(DataFormats.Text));
}
DataFormats.TextA vágólap sima szöveges formátuma.
Paste(formátum)Csak a megadott formátumú tartalmat illeszti be, így a másolt szöveg a kurzor helyén álló formázást kapja.

Egy másik fontos részlet: a fájl megnyitása után a felhasználó a Visszavonás gombbal visszavonhatná a betöltést is, és üres dokumentumot kapna. Ezt megelőzheted, ha a betöltés után törlöd a visszavonási előzményeket:

Form1.cs, a Megnyitas() metódusban a LoadFile utánC#
rtbDokumentum.LoadFile(fajl, RichTextBoxStreamType.RichText);
rtbDokumentum.ClearUndo();

Ellenőrizd a saját gépeden

Nyiss meg egy fájlt, majd válaszd a Visszavonást. A viselkedés a betöltés módjától függhet, ezért érdemes a ClearUndo() hívást betenni: így a megnyitás után biztosan tiszta az előzmény.

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 menüpontok mindig engedélyezettek

A Visszavonás akkor is használható, ha nincs mit visszavonni.

Ok és javítás

Nincs beállítva az Enabled tulajdonság. Állítsd be a főmenü DropDownOpening eseményében a CanUndo és a többi tulajdonság alapján.

2. Kétszer illeszti be a szöveget

A Ctrl+V megnyomására a szöveg kétszer jelenik meg.

Ok és javítás

A gyorsbillentyűt két helyen is kezeled: a RichTextBox beépített kezelése és a menüpont ShortcutKeys tulajdonsága is lefut. Töröld a ShortcutKeys beállítást, és csak a ShortcutKeyDisplayString tulajdonságot használd megjelenítésre.

3. A Redo szürke marad

Visszavonsz egy gépelést, de az Újra menüpont szürke.

Ok és javítás

A DropDownOpening eseménykezelő nincs összekötve a menüponttal (kézzel gépelted be), vagy hiányzik belőle az miUjra.Enabled = rtbDokumentum.CanRedo; sor. Hozd létre az eseménykezelőt az Events nézetben, a DropDownOpening sornál.

4. Nem a kijelölt szöveget másolja

Clipboard.SetText(rtbDokumentum.Text);
Hiba és javítás

Rossz működés: ez az egész dokumentum szövegét másolja, nem csak a kijelöltet. A kijelölt szöveg másolásához a rtbDokumentum.Copy() vagy a Clipboard.SetText(rtbDokumentum.SelectedText) kell. A vágólapról a 2.13 lecke szól.

5. A betöltött fájl visszavonható

Megnyitsz egy fájlt, majd a Visszavonás után üres lesz a dokumentum.

Ok és javítás

A betöltés is bekerült a visszavonási előzménybe. A LoadFile után hívd meg a rtbDokumentum.ClearUndo(); metódust.

Mini projekt: Szerkesztés menü a MiniWordben

Építsd be a Szerkesztés menüt a MiniWordbe:

  1. Menüpontok: Visszavonás, Újra, Kivágás, Másolás, Beillesztés, Sima szöveg beillesztése, Mindent kijelöl, a megfelelő elválasztókkal.
  2. Az egysoros eseménykezelők a 2. szakasz kódja szerint.
  3. A miSzerkesztes_DropDownOpening a menüpontok állapotát frissíti.
  4. A Megnyitas() metódus a LoadFile után hívja a ClearUndo() metódust.
  5. Próbáld ki: gépelj, vonj vissza, ismételd meg, jelölj ki, másolj, illessz be. Másolj formázott szöveget a Wordből, és illeszd be a Sima szöveg beillesztése menüponttal.
📷 Képernyőkép helye

Mit tegyél ide: a MiniWord kijelölt szöveggel és lenyitott Szerkesztés menüvel: a Másolás és Kivágás engedélyezett, a menüpontok mellett a billentyűkombinációk látszanak.Javasolt fájlnév: winforms-2-12-miniword-szerkesztes.webp · Alt szöveg: A kész Szerkesztés menü a MiniWordben kijelölt szöveggel

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. Törlés a kijelölésre

Adj a menühöz egy Törlés elemet, amely a kijelölt szöveget a vágólap használata nélkül törli.

Egy lehetséges megoldás
private void miTorles_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectedText = "";
}

A SelectedText értékadással lecseréli a kijelölt szöveget, üres szövegre cserélve pedig törli.

2. Dátum beszúrása

Készíts egy Beszúrás → Mai dátum menüpontot, amely a kurzor helyére beírja a mai dátumot.

Egy lehetséges megoldás
private void miDatum_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectedText = DateTime.Today.ToString("yyyy. MM. dd.");
}

Ha van kijelölt szöveg, a dátum lecseréli. Ha nincs, a kurzor helyére kerül.

3. A visszavonás neve

A Visszavonás menüpont felirata mutassa meg, mit vonna vissza, például Visszavonás (Typing).

Egy lehetséges megoldás
// a DropDownOpening eseménykezelőben:
if (rtbDokumentum.CanUndo)
{
miVisszavon.Text = "Visszavonás (" + rtbDokumentum.UndoActionName + ")";
}
else
{
miVisszavon.Text = "Visszavonás";
}

Az UndoActionName a következő visszavonható művelet neve (például Typing vagy Paste). A pontos szöveg a Windows nyelvi beállításától függhet.

Gyakorlótár: 6 további feladat

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

Alap szint

1. Törlés a kijelölésre

A Szerkesztés → Törlés menüpont törölje a kijelölt szöveget a vágólap használata nélkül.

Megoldás megnyitása

A SelectedText értékadással lecseréli a kijelölt szöveget, üres szöveggel pedig törli. A vágólap tartalma nem változik.

Form1.csC#
private void miTorles_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectedText = "";
}

2. Szürke menüpontok

A Visszavonás és az Újra menüpont csak akkor legyen engedélyezett, ha van mit visszavonni, illetve újra végrehajtani. Mikor és hol állítod be?

Megoldás megnyitása

A főmenü DropDownOpening eseményében, mert az a menü lenyitása előtt fut le. A CanUndo és a CanRedo megmondja az állapotot.

Form1.csC#
private void miSzerkesztes_DropDownOpening(object sender, EventArgs e)
{
miVisszavon.Enabled = rtbDokumentum.CanUndo;
miUjra.Enabled = rtbDokumentum.CanRedo;
}

Közepes szint

3. Beillesztés sima szövegként

A Szerkesztés → Beillesztés sima szövegként menüpont a vágólap tartalmát formázás nélkül illessze be.

Megoldás megnyitása

A Paste metódus egy formátumot is megkaphat. A DataFormats.Text csak a nyers szöveget illeszti be, így a másolt tartalom formázása nem kerül át.

Form1.csC#
private void miSimaBeillesztes_Click(object sender, EventArgs e)
{
rtbDokumentum.Paste(DataFormats.GetFormat(DataFormats.Text));
}

4. Dátum beszúrása

A Beszúrás → Mai dátum menüpont a kurzor helyére írja be a mai dátumot (2026. 10. 25.). Ha van kijelölt szöveg, azt cserélje le.

Megoldás megnyitása

A SelectedText a kurzor helyére szúr be, ha nincs kijelölés, és lecseréli a kijelöltet, ha van.

Form1.csC#
private void miDatum_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectedText = DateTime.Today.ToString("yyyy. MM. dd.");
}

Kihívás szint

5. A visszavonás neve a menüben

A Visszavonás menüpont felirata mutassa, mit vonna vissza: Visszavonás (Typing).

Megoldás megnyitása

Az UndoActionName a következő visszavonható művelet neve. A szöveg a rendszer nyelvétől függhet. Ha nincs mit visszavonni, az eredeti feliratot állítjuk vissza.

Form1.csC#
private void miSzerkesztes_DropDownOpening(object sender, EventArgs e)
{
miVisszavon.Enabled = rtbDokumentum.CanUndo;

if (rtbDokumentum.CanUndo)
{
miVisszavon.Text = "Visszavonás (" + rtbDokumentum.UndoActionName + ")";
}
else
{
miVisszavon.Text = "Visszavonás";
}
}

6. Kijelölt szöveg duplázása

Egy menüpont duplázza meg a kijelölt szöveget (alma → almaalma). Ha nincs kijelölés, szóljon.

Megoldás megnyitása

A kijelölés után a szöveg lecserélődik az önmagával kétszer összefűzött változatra. Utána a Visszavonás menüpontnak vissza kell tudnia vonni a változtatást: ezt érdemes kipróbálni.

Form1.csC#
private void miDuplaz_Click(object sender, EventArgs e)
{
if (rtbDokumentum.SelectionLength == 0)
{
MessageBox.Show("Előbb jelölj ki szöveget!");
return;
}

string kijelolt = rtbDokumentum.SelectedText;
rtbDokumentum.SelectedText = kijelolt + kijelolt;
}

Gyors önellenőrzés

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

1. Melyik tulajdonság mondja meg, van-e mit visszavonni?

A CanUndo. Hasonlóan a CanRedo az újra végrehajtásra vonatkozik.

2. Miért a DropDownOpening eseményben frissítjük a menüpontokat?

Mert az a menü megnyitása előtt egyszer fut le, és elég ekkor beállítani az állapotukat. A SelectionChanged minden kurzormozgásnál lefutna.

3. Mit csinál a Cut()?

A kijelölt szöveget a vágólapra teszi, és törli a dokumentumból.

4. Miért elég a ShortcutKeyDisplayString a gyorsbillentyűhöz?

Mert a RichTextBox a billentyűket már kezeli. A menü csak megmutatja őket, így nincs kétszeres kezelés.

5. Hogyan illesztesz be sima szöveget?

A Paste(DataFormats.GetFormat(DataFormats.Text)) metódussal.

6. Mire való a ClearUndo?

Törli a visszavonási előzményeket, például fájl betöltése után, hogy ne lehessen visszavonni a betöltést.

Mit tudsz már?

  • Használod a RichTextBox beépített szerkesztő műveleteit.
  • Szerkesztés menüt építesz.
  • A menüpontok állapotát a DropDownOpening eseményben frissíted.
  • Sima szöveget illesztesz be.
  • Törlöd a visszavonási előzményeket a megnyitás után.

Következő lecke: Clipboard és vágólapkezelés

A beépített műveletek kényelmesek. A következő leckében megnézzük, hogyan éred el közvetlenül a vágólapot a kódból.