Grafikus C# – Windows Forms tanfolyam › 2.13 lecke

Windows Forms · 2.13 lecke

Clipboard és vágólapkezelés

A vágólapot a RichTextBox beépített műveletein kívül közvetlenül is elérheted a kódból. Ez akkor hasznos, ha egy gombbal szöveget, formázott tartalmat vagy képet szeretnél a vágólapra tenni, vagy onnan beolvasni. Megnézzük a Clipboard osztály főbb metódusait, és azt is, mire kell vigyázni.

  • kb. 60 perc
  • közepes szint
  • vágólap
Diáklány C# programot készít laptopon

A lecke végére

  • a Clipboard.SetText() és a Clipboard.GetText() metódussal szöveget teszel a vágólapra, illetve olvasol róla;
  • a Clipboard.ContainsText() segítségével ellenőrzöd, van-e szöveg a vágólapon;
  • képet másolsz és illesztesz be (SetImage, GetImage);
  • formázott (RTF) szöveget másolsz a SelectedRtf segítségével;
  • a vágólap hibáit kezeled try–catch blokkal;
  • ismered a vágólap biztonsági szempontjait.

Mielőtt elkezded

Ehhez a leckéhez kell a MiniWord a 2.12 lecke után, a try–catch (2.2 lecke) és a PictureBox ismerete (1.12 lecke).

2.12 Undo, Redo, Copy, Cut és Paste →

Szöveg a vágólapon

A Clipboard egy beépített osztály, amelynek metódusait közvetlenül hívhatod (nem kell létrehozni belőle objektumot):

Clipboard.SetText(szöveg)A megadott szöveget a vágólapra teszi.
Clipboard.GetText()Visszaadja a vágólapon lévő szöveget. Ha nincs ott szöveg, üres szöveget ad vissza.
Clipboard.ContainsText()Igaz, ha a vágólapon szöveg van.
Clipboard.Clear()Kiüríti a vágólapot.
Form1.csC#
private void btnMasolSzoveg_Click(object sender, EventArgs e)
{
if (rtbDokumentum.SelectionLength > 0)
{
Clipboard.SetText(rtbDokumentum.SelectedText);
}
else
{
MessageBox.Show("Előbb jelölj ki szöveget!");
}
}

private void btnBeillesztSzoveg_Click(object sender, EventArgs e)
{
if (Clipboard.ContainsText())
{
rtbDokumentum.SelectedText = Clipboard.GetText();
}
}
SelectedTextA kijelölt szöveg. Ha értéket adsz neki, lecseréli a kijelölést, vagy a kurzor helyére beszúrja.
SelectionLength > 0Ellenőrzés: kell lennie kijelölt szövegnek. Üres szöveggel a SetText hibát dobna.
if (Clipboard.ContainsText())Csak akkor illesztünk be, ha a vágólapon tényleg szöveg van.

Jósolj!

A vágólap üres (vagy csak kép van rajta). Mit ad vissza a Clipboard.GetText()? És mit ad a Clipboard.ContainsText()?

Jóslat ellenőrzése

A GetText() üres szöveget ("") ad vissza, hiba nélkül. A ContainsText() false értéket ad. Az ellenőrzéssel elkerülhető, hogy üres szöveget illessz be.

📷 Képernyőkép helye

Mit tegyél ide: a MiniWord két gombbal (Szöveg másolása, Szöveg beillesztése), egy kijelölt mondattal, és mellette a Jegyzettömb, amelybe a másolt szöveget beillesztetted (Ctrl+V).Javasolt fájlnév: winforms-2-13-szoveg-masolas.webp · Alt szöveg: A kijelölt szöveg másolása a vágólapra és beillesztése a Jegyzettömbbe

Amikor a vágólap nem elérhető

A vágólapot a Windows minden futó program között megosztja. Előfordulhat, hogy egy másik program éppen használja, és a művelet sikertelen (a hiba típusa ExternalException). A kockázatos hívást ezért tedd try–catch blokkba:

Form1.csC#
private void VagolapraMasol(string szoveg)
{
try
{
Clipboard.SetText(szoveg);
}
catch (Exception ex)
{
MessageBox.Show("A vágólap most nem elérhető: " + ex.Message);
}
}
VagolapraMasol(string szoveg)Saját metódus, amely biztonságosan másol. Bárhonnan hívható a programból.
try–catchHa a vágólap foglalt, a program nem omlik össze, hanem üzenetet mutat.

Miért kell az [STAThread]?

A vágólap csak olyan programszálról érhető el, amelyet a Windows egyszálú lakásnak (STA) jelölt meg. A Windows Forms projekt Program.cs fájljában ezért áll az [STAThread] jelölés a Main előtt (0.8 lecke). Ha törölnéd, a Clipboard hívások hibát dobnának.

Kép és formázott szöveg

A vágólapra nem csak sima szöveg kerülhet. Néhány további lehetőség:

Clipboard.SetImage(kép)Képet tesz a vágólapra.
Clipboard.GetImage()A vágólapon lévő képet adja vissza (Image).
Clipboard.ContainsImage()Igaz, ha a vágólapon kép van.
rtbDokumentum.SelectedRtfA kijelölt szöveg formázással együtt, RTF formátumban.
Form1.csC#
// kép beillesztése a PictureBoxba:
if (Clipboard.ContainsImage())
{
pbKep.Image = Clipboard.GetImage();
}

// kép másolása a vágólapra:
if (pbKep.Image != null)
{
Clipboard.SetImage(pbKep.Image);
}

// formázott szöveg másolása (RTF):
if (rtbDokumentum.SelectionLength > 0)
{
Clipboard.SetText(rtbDokumentum.SelectedRtf, TextDataFormat.Rtf);
}
TextDataFormat.RtfAzt jelzi, hogy a szöveg RTF formátumú, formázással együtt. A Word is érti, és formázva illeszti be.
Miért két ellenőrzés?A kép és a szöveg különálló: a vágólapon lehet csak szöveg, csak kép, vagy mindkettő.

Jósolj!

A MiniWordből egy félkövér szót SelectedText segítségével másolsz a vágólapra, majd beilleszted a Wordbe. Félkövér lesz? Mi változik, ha a SelectedRtf formátumot használod?

Jóslat ellenőrzése

A SelectedText csak a nyers szöveget másolja, ezért a Wordben nem lesz félkövér. A SelectedRtf és a TextDataFormat.Rtf használatával a formázás is átmegy, és a szó félkövér marad.

A vágólap és a biztonság

A vágólap bizalmas adatot is tartalmazhat

A felhasználó a vágólapra jelszót, bankkártyaszámot vagy más személyes adatot is másolhat. A programod ezért csak akkor olvassa a vágólapot, amikor a felhasználó kéri (például egy Beillesztés gomb megnyomásakor). Ne figyeld folyamatosan, és soha ne küldd el vagy tárold a tartalmát a felhasználó tudta nélkül. A vágólapot ne használd titkos adatok átmeneti tárolására.

Beillesztés gomb állapota

A 2.12 lecke Szerkesztés menüjében a Beillesztés menüpont csak akkor lehet engedélyezett, ha a vágólapon van szöveg: miBeillesztes.Enabled = Clipboard.ContainsText(); Ezt a DropDownOpening eseménykezelőbe tedd. Ilyenkor csak azt vizsgálod, van-e szöveg, a tartalmát nem olvasod.

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. Üres szöveg másolása

Clipboard.SetText(rtbDokumentum.SelectedText);
// kijelölés nélkül ArgumentNullException
Hiba és javítás

Futás közbeni hiba: ha nincs kijelölt szöveg, a SelectedText üres, és a SetText ilyet nem fogad el. Előbb ellenőrizd: if (rtbDokumentum.SelectionLength > 0).

2. A vágólap foglalt

Időnként „Requested Clipboard operation did not succeed” hibaüzenet jelenik meg.

Ok és javítás

Egy másik program éppen használja a vágólapot. A hívást tedd try–catch blokkba, és mutass érthető üzenetet, vagy próbáld meg újra egy kis várakozás után.

3. A beillesztett szöveg üres

A Beillesztés gomb megnyomása után nem jelenik meg semmi.

Ok és javítás

A vágólapon valószínűleg nem szöveg van (például kép), így a GetText() üres szöveget ad. Ellenőrizd a Clipboard.ContainsText() eredményét, és ha hamis, jelezd a felhasználónak.

4. A formázás elveszik

A Wordbe beillesztett szöveg nem őrzi meg a félkövér formázást.

Ok és javítás

A SelectedText csak nyers szöveget másol. Formázott másoláshoz használd a Clipboard.SetText(rtb.SelectedRtf, TextDataFormat.Rtf) hívást.

5. Hiányzó kép

pbKep.Image = Clipboard.GetImage();
Hiba és javítás

Rossz működés: ha a vágólapon nincs kép, a GetImage() null értéket ad, és a PictureBox kiürül. Előbb ellenőrizd a Clipboard.ContainsImage() eredményét.

Mini projekt: vágólap-eszköztár

Bővítsd a MiniWordöt egy kis vágólap-eszköztárral:

  1. Gombok: btnMasolSzoveg (kijelölt szöveg másolása nyersen), btnMasolFormazott (RTF másolása), btnBeillesztSzoveg (beillesztés sima szövegként).
  2. Egy lblVagolap felirat mutassa a vágólap tartalmának első 30 karakterét. Egy tmrVagolap Timer (Interval: 1000) ezt másodpercenként frissíti, de csak szöveg esetén olvas.
  3. Minden vágólaphívás try–catch blokkban fusson.
Megoldás megnyitása (próbáld ki előbb önállóan!)
Form1.csC#
private void btnMasolFormazott_Click(object sender, EventArgs e)
{
if (rtbDokumentum.SelectionLength == 0)
{
MessageBox.Show("Előbb jelölj ki szöveget!");
return;
}

try
{
Clipboard.SetText(rtbDokumentum.SelectedRtf, TextDataFormat.Rtf);
}
catch (Exception ex)
{
MessageBox.Show("A vágólap most nem elérhető: " + ex.Message);
}
}

private void tmrVagolap_Tick(object sender, EventArgs e)
{
try
{
if (Clipboard.ContainsText())
{
string szoveg = Clipboard.GetText();

if (szoveg.Length > 30)
{
szoveg = szoveg.Substring(0, 30) + "...";
}

lblVagolap.Text = "Vágólap: " + szoveg;
}
else
{
lblVagolap.Text = "Vágólap: (nincs szöveg)";
}
}
catch (Exception)
{
lblVagolap.Text = "Vágólap: (nem elérhető)";
}
}

Gyakorlásra jó, élesben nem

A vágólap másodpercenkénti olvasása gyakorlásra jó, de valódi programban a biztonsági szabály szerint nem szabad a felhasználó tudta nélkül olvasni. Használd csak a gyakorláshoz, és tedd mellé egy kapcsolót, amellyel a felhasználó be- és kikapcsolhatja.

📷 Képernyőkép helye

Mit tegyél ide: a MiniWord a három vágólap-gombbal és a „Vágólap: Az alma körte…” felirattal.Javasolt fájlnév: winforms-2-13-vagolap-eszkoztar.webp · Alt szöveg: A MiniWord vágólap-eszköztára a vágólap tartalmával

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. A dokumentum másolása egy gombbal

Egy btnMindenMasol gomb a teljes dokumentum szövegét másolja a vágólapra, ha van benne szöveg.

Egy lehetséges megoldás
if (rtbDokumentum.Text.Length > 0)
{
Clipboard.SetText(rtbDokumentum.Text);
MessageBox.Show("A teljes szöveg a vágólapon van.");
}

2. Kép a vágólapról

Tegyél az ablakra egy pbKep PictureBoxot és egy gombot, amely a vágólapon lévő képet megjeleníti (ha van ott kép).

Egy lehetséges megoldás
if (Clipboard.ContainsImage())
{
pbKep.Image = Clipboard.GetImage();
pbKep.SizeMode = PictureBoxSizeMode.Zoom;
}
else
{
MessageBox.Show("A vágólapon nincs kép.");
}

Próbáld ki: nyomd meg a Print Screen billentyűt (képernyőkép a vágólapra), és utána kattints a gombra.

3. Beillesztés menüpont

A Szerkesztés menü Beillesztés pontja csak akkor legyen engedélyezett, ha a vágólapon szöveg van.

Egy lehetséges megoldás
// a miSzerkesztes_DropDownOpening eseménykezelőben:
miBeillesztes.Enabled = Clipboard.ContainsText();

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. A vágólapot csak a felhasználó kérésére használjuk. Csak a próbálkozás után nyisd le a megoldást.

Alap szint

1. A kijelölt szöveg a vágólapra

A btnMasol gomb tegye a kijelölt szöveget a vágólapra. Kijelölés nélkül szóljon.

Megoldás megnyitása

A Clipboard.SetText üres szöveggel hibát adna, ezért előbb ellenőrizzük a SelectionLength értékét.

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

Clipboard.SetText(rtbDokumentum.SelectedText);
}

2. Beillesztés, ha van szöveg

A btnBeillesztes gomb a vágólap szövegét illessze a kurzor helyére, de csak ha a vágólapon szöveg van.

Megoldás megnyitása

A Clipboard.ContainsText() megmondja, hogy van-e szöveg a vágólapon. A GetText() üres szöveget adna vissza, ha nincs, de az ellenőrzés érthetőbb viselkedést ad.

Form1.csC#
private void btnBeillesztes_Click(object sender, EventArgs e)
{
if (Clipboard.ContainsText())
{
rtbDokumentum.SelectedText = Clipboard.GetText();
}
else
{
MessageBox.Show("A vágólapon nincs szöveg.");
}
}

Közepes szint

3. Kép a vágólapról

A btnKepBeillesztes gomb a vágólapon lévő képet jelenítse meg a pbKep PictureBoxban. Ha nincs kép, jelezzen. Próbáld ki a Print Screen billentyűvel.

Megoldás megnyitása

A ContainsImage() a kép meglétét vizsgálja. A GetImage() a képet adja vissza, amelyet a PictureBox Image tulajdonságának adunk. A SizeMode legyen Zoom, hogy a kép beleférjen.

Form1.csC#
private void btnKepBeillesztes_Click(object sender, EventArgs e)
{
if (Clipboard.ContainsImage())
{
pbKep.Image = Clipboard.GetImage();
}
else
{
MessageBox.Show("A vágólapon nincs kép.");
}
}

4. Formázott másolás

A btnMasolFormazott gomb a kijelölt szöveget formázással együtt (RTF-ként) tegye a vágólapra.

Megoldás megnyitása

A SelectedRtf a kijelölt szöveget RTF formátumban adja, a TextDataFormat.Rtf pedig jelzi a vágólapnak, hogy a szöveg RTF. Így a Word formázva illeszti be.

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

Clipboard.SetText(rtbDokumentum.SelectedRtf, TextDataFormat.Rtf);
}

Kihívás szint

5. Saját másolási előzmények

Minden másolás után kerüljön a másolt szöveg egy lstElozmeny ListBox tetejére (legfeljebb 5 elem). Egy elemre duplán kattintva a szöveg kerüljön vissza a vágólapra. Az előzmény a program saját listája, nem a Windows vágólap-előzménye.

Megoldás megnyitása

Az Items.Insert(0, ...) a lista elejére illeszt. Ha öt elemnél több lenne, az utolsót töröljük. A dupla kattintás a DoubleClick eseményt használja. Tervezői szempont: a program csak a saját, felhasználó által indított másolásokat jegyzi meg, a vágólapot nem figyeli folyamatosan.

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

string szoveg = rtbDokumentum.SelectedText;
Clipboard.SetText(szoveg);

lstElozmeny.Items.Insert(0, szoveg);

if (lstElozmeny.Items.Count > 5)
{
lstElozmeny.Items.RemoveAt(5);
}
}

private void lstElozmeny_DoubleClick(object sender, EventArgs e)
{
if (lstElozmeny.SelectedItem != null)
{
Clipboard.SetText(lstElozmeny.SelectedItem.ToString());
}
}

6. A vágólap ürítése

A btnUrit gomb a felhasználó megerősítése után ürítse ki a vágólapot. Miért kell megerősítés?

Megoldás megnyitása

A Clipboard.Clear() a teljes rendszer vágólapját törli, amelyet a felhasználó más programokban is használ (például egy fontos szöveg, amelyet másolt). Ezért csak a felhasználó külön megerősítése után, és csak akkor szabad, ha tényleg ez a gomb célja.

Form1.csC#
private void btnUrit_Click(object sender, EventArgs e)
{
DialogResult valasz = MessageBox.Show("Biztosan kiüríted a vágólapot?", "Vágólap", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

if (valasz == DialogResult.Yes)
{
Clipboard.Clear();
}
}

Gyors önellenőrzés

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

1. Mit ad vissza a Clipboard.GetText(), ha a vágólapon nincs szöveg?

Üres szöveget, hiba nélkül.

2. Mire való a Clipboard.ContainsText()?

Megmondja, hogy van-e szöveg a vágólapon.

3. Mi a különbség a SelectedText és a SelectedRtf másolása között?

A SelectedText nyers szöveg, a SelectedRtf formázással együtt másol (a TextDataFormat.Rtf formátummal).

4. Miért kell try–catch a Clipboard hívásoknál?

Mert a vágólapot egy másik program használhatja, és ilyenkor a művelet sikertelen lehet.

5. Miért kell az [STAThread] a Main előtt?

Mert a vágólap csak egyszálú lakásként (STA) jelölt szálról érhető el.

6. Miért nem szabad a vágólapot a felhasználó tudta nélkül olvasni?

Mert bizalmas adatot (jelszó, bankkártya) tartalmazhat, és ennek védelme a program felelőssége.

Mit tudsz már?

  • Szöveget teszel a vágólapra és olvasol róla.
  • Ellenőrzöd, mi van a vágólapon.
  • Képet és formázott szöveget másolsz.
  • Kezeled a vágólap hibáit.
  • Ismered a biztonsági szempontokat.

Következő lecke: mentetlen dokumentum és bezárás megerősítése

A vágólap kész. A következő leckében a MiniWord megtanulja, hogy ne engedje elveszni a nem mentett munkát.