Grafikus C# – Windows Forms tanfolyam › 2.3 lecke Windows Forms · 2.3 lecke A MiniWord már meg tud nyitni fájlokat, de ami benne készül, az eddig elveszett, amint bezárod. Most megtanítjuk menteni: a felhasználó megadja a fájl nevét és helyét, a program pedig RTF fájlba írja a dokumentumot, formázással együtt.SaveFileDialog – dokumentum mentése RTF-ként

A lecke végére
- elhelyezel egy
SaveFileDialogkomponenst, és beállítod a szűrőjét; - a
DefaultExtés azAddExtensionsegítségével gondoskodsz róla, hogy a fájl végén ott legyen a.rtf; - a
SaveFile()metódussal elmented a dokumentumot formázással együtt; - kezeled, ha a mentés nem sikerül;
- ellenőrzöd, hogy a mentett fájl megnyitható a MiniWordben és a Wordben is;
- tudod, mit tartalmaz egy RTF fájl, ha szövegként nyitod meg.
Mielőtt elkezded
Ehhez a leckéhez kell a MiniWord a 2.2 lecke után, vagyis a működő Megnyitas() metódussal. A mentés ugyanazt a mintát követi, mint a megnyitás.
A SaveFileDialog komponens
A mentés párbeszédablaka a megnyitáséhoz hasonlóan működik, ezért ugyanazokat a lépéseket követjük:
- Húzz az ablakra egy
Button-t:(Name):btnMentes,Text:Mentés. Tedd a Megnyitás gomb mellé. - A Toolbox Dialogs csoportjából húzd az ablakra a
SaveFileDialogelemet. Alul, a komponenssávban fog megjelenni. - Állítsd a
(Name)tulajdonságátsfdMentes-re. Azsfda SaveFileDialog rövidítése.
Mit tegyél ide: a MiniWord Designer nézete. Fent a Megnyitás és a Mentés gomb egymás mellett, alul a komponenssávban az ofdMegnyitas és az sfdMentes ikon.Javasolt fájlnév: winforms-2-3-savefiledialog-komponens.webp · Alt szöveg: A SaveFileDialog komponens a Visual Studio tervezőjének komponenssávjában
Te jössz!
Add hozzá a Mentés gombot és az sfdMentes komponenst. Készíts a gombhoz Click eseménykezelőt dupla kattintással, de a kódot még ne írd meg.
Szűrő és kiterjesztés
A felhasználó megadja a fájl nevét, de a program felel azért, hogy a fájl RTF legyen. Ehhez négy tulajdonságot állítunk be:
RTF dokumentum (*.rtf)|*.rtf.rtf.true, a program hozzáteszi a kiterjesztést, ha a felhasználó elfelejtette begépelni.dokumentum. A felhasználó átírhatja.Ha például a felhasználó azt írja a névmezőbe, hogy level, és az AddExtension be van kapcsolva, akkor a fájl neve level.rtf lesz.
Jósolj!
Mi történik, ha a felhasználó ugyanolyan nevet ad meg, amilyen fájl már létezik a mappában?
Jóslat ellenőrzése
A Windows megkérdezi, hogy felülírja-e a meglévő fájlt. Ezt az OverwritePrompt tulajdonság vezérli, amely alapból be van kapcsolva, így nem kell kódot írnunk hozzá.
A dokumentum mentése: SaveFile
A mentés lényege egyetlen sor. A SaveFile() a szövegdoboz tartalmát a megadott fájlba írja. A második paraméter, a RichTextBoxStreamType.RichText azt mondja meg, hogy RTF formátumban, a formázással együtt kell menteni.
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);C:\Teszt\level.rtf.Ne a PlainText típust használd!
Ha RichTextBoxStreamType.PlainText típussal mentesz, a fájlban csak a nyers szöveg lesz, a formázás elvész. Ráadásul a kiterjesztés .rtf marad, ezért a Word és a MiniWord is megpróbálja RTF-ként megnyitni.
A teljes Mentes() metódus
Ugyanazt a szerkezetet építjük fel, mint a megnyitásnál: saját metódus, DialogResult ellenőrzés és try–catch. A mentés is meghiúsulhat: ha a fájl éppen meg van nyitva a Wordben, vagy a mappába nincs írási jogosultságod, a SaveFile hibával áll meg.
private void btnMentes_Click(object sender, EventArgs e)
{
Mentes();
}
private void Mentes()
{
sfdMentes.Title = "Dokumentum mentése";
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
sfdMentes.DefaultExt = "rtf";
sfdMentes.AddExtension = true;
sfdMentes.FileName = "dokumentum";
if (sfdMentes.ShowDialog() == DialogResult.OK)
{
try
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
MessageBox.Show("A dokumentum mentve.");
}
catch (Exception ex)
{
MessageBox.Show("Nem sikerült menteni a fájlt: " + ex.Message);
}
}
}Mit tegyél ide: a futó MiniWord Mentés másként ablaka. A típuslistában „RTF dokumentum (*.rtf)”, a fájlnév mezőben a „dokumentum” javaslat látszik, a címsorban pedig „Dokumentum mentése”.Javasolt fájlnév: winforms-2-3-mentes-ablak.webp · Alt szöveg: A MiniWord mentés ablaka RTF típussal és javasolt fájlnévvel
Működik!
Nyiss meg a Megnyitás gombbal egy formázott RTF fájlt (például a teszt.rtf-et), írj hozzá egy mondatot, majd kattints a Mentés gombra, és adj meg egy új fájlnevet. A Megnyitas() ugyanezt a fájlt visszatölti.
Mi van valójában az RTF fájlban?
Az RTF szöveges formátum, ezért Jegyzettömbbel is megnyithatod. Kattints jobb gombbal a mentett fájlra, és válaszd a Megnyitás ezzel → Jegyzettömb lehetőséget.
Jósolj!
Mit fogsz látni, ha egy Szia szót tartalmazó dokumentum mentett fájlját Jegyzettömbben nyitod meg? Csak a Szia szót?
Jóslat ellenőrzése
Nem. A fájl elején formázási kódok állnak, például {\rtf1\ansi ...}, és csak valahol közöttük látod a Szia szót. Ezt kapod meg a 2.1 leckében megismert Rtf tulajdonságból is: a SaveFile lényegében ezt a szöveget írja a fájlba.
Mit tegyél ide: a MiniWord által mentett .rtf fájl Jegyzettömbben megnyitva. Látszódjanak a kapcsos zárójeles RTF kódok az elején, és közöttük a mentett szöveg.Javasolt fájlnév: winforms-2-3-rtf-jegyzettombben.webp · Alt szöveg: Egy mentett RTF fájl tartalma Jegyzettömbben: formázási kódok és a szöveg
Mit tegyél ide: ugyanaz a mentett fájl a Wordben megnyitva, normál szerkesztőnézetben. Így látható, hogy a MiniWord által mentett fájlt más program is érti.Javasolt fájlnév: winforms-2-3-rtf-wordben.webp · Alt szöveg: A MiniWordben mentett RTF dokumentum megnyitva a Wordben
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. Kiterjesztés nélküli név
A névmezőbe azt írod, hogy level.rtf. A level, és kattintasz a Mentés gombra. Hogy hívják a létrejött fájlt?Jóslat ellenőrzése
DefaultExt és az AddExtension hozzátette a kiterjesztést.
2. Mégse
Megnyitod a mentés ablakot, majd a Mégse gombra kattintasz. Keletkezik fájl? Megjelenik üzenet? Nem keletkezik fájl, és üzenet sem jelenik meg, mert a Jóslat ellenőrzése
ShowDialog() eredménye Cancel, ezért az if blokk nem fut le.
3. Kerek út
Elmented a dokumentumot, bezárod a MiniWordöt, újraindítod, majd megnyitod ugyanazt a fájlt. Mit látsz? Ugyanazt a szöveget, ugyanazzal a formázással. Ez az újranyitási teszt: ha ezt meg tudod csinálni, a mentés és a megnyitás együtt működik.Jóslat ellenőrzése
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. Elveszett formázás
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.PlainText);Hiba és javítás
Rossz működés: a félkövér és a többi formázás nem kerül a fájlba. Javítás: RichTextBoxStreamType.RichText.
2. Kiterjesztés nélküli fájl
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
// DefaultExt és AddExtension nincs beállítvaHiba és javítás
Ha a felhasználó csak annyit ír, hogy level, a fájl kiterjesztés nélkül jöhet létre, és a Windows nem tudja, melyik programmal nyissa meg. Javítás: sfdMentes.DefaultExt = "rtf"; és sfdMentes.AddExtension = true;
3. Üres elérési út
sfdMentes.ShowDialog();
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);Hiba és javítás
Futás közbeni hiba, ha a felhasználó a Mégse gombot választja: nincs fájlnév, a SaveFile pedig mégis megpróbál menteni. Javítás: ellenőrizd a ShowDialog() eredményét az if (... == DialogResult.OK) szerkezettel.
4. Nyitva lévő fájl
A mentendő fájl éppen meg van nyitva a Wordben, a MiniWord pedig összeomlik a mentéskor.
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
// IOException: a fájlt másik folyamat használjaHiba és javítás
Futás közbeni hiba (IOException): a Word zárolja a fájlt. Ilyenkor a program nem tud rá írni. Javítás: tedd a mentést try blokkba, a catch pedig mutasson érthető üzenetet a felhasználónak.
5. Két külön mentési kód
// btnMentes_Click-ben is és később a menüben is ugyanaz a hosszú kódHiba és javítás
Ha ugyanaz a mentési kód két helyen van, a javítást mindkét helyen el kell végezni, és előbb-utóbb eltér a kettő. Ezért tettük a kódot a Mentes() metódusba: a gomb és a File menü is csak meghívja.
Mini projekt: a MiniWord ment
Bővítsd a MiniWordöt a Mentés gombbal. A Az újranyitási teszt: nyiss meg egy RTF fájlt a Megnyitás gombbal, írj hozzá egy mondatot, mentsd el új néven, majd nyisd meg az új fájlt a Wordben is. Ha mindhárom helyen ugyanazt látod, a mentés és a megnyitás együtt működik.Megnyitas() metódus és a többi rész változatlan marad, a következőket add hozzá a Form1 osztályhoz. 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
private void btnMentes_Click(object sender, EventArgs e)
{
Mentes();
}
private void Mentes()
{
sfdMentes.Title = "Dokumentum mentése";
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
sfdMentes.DefaultExt = "rtf";
sfdMentes.AddExtension = true;
sfdMentes.FileName = "dokumentum";
if (sfdMentes.ShowDialog() == DialogResult.OK)
{
try
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
MessageBox.Show("A dokumentum mentve.");
}
catch (Exception ex)
{
MessageBox.Show("Nem sikerült menteni a fájlt: " + ex.Message);
}
}
}
Önálló gyakorlófeladatok
Először készíts saját megoldást. A lenyitható rész csak ellenőrzéshez van.
1. A mentett fájl neve az üzenetben
A sikeres mentés után az üzenet mondja meg, melyik fájlba mentett a program.Egy lehetséges megoldás
MessageBox.Show("Mentve ide: " + sfdMentes.FileName);
2. Üres dokumentum
Ha a dokumentum üres, a program ne nyissa meg a mentés ablakot, hanem jelezze, hogy nincs mit menteni. A Egy lehetséges megoldás
private void Mentes()
{
if (rtbDokumentum.Text.Length == 0)
{
MessageBox.Show("Nincs mit menteni, a dokumentum üres.");
return;
}
// ... a többi kód változatlan
}return kilép a metódusból, a többi kód már nem fut le.
3. A fájl neve az ablak címében
Sikeres mentés után az ablak címsora legyen például MiniWord – level.rtf. A Egy lehetséges megoldás
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
this.Text = "MiniWord – " + Path.GetFileName(sfdMentes.FileName);Path használatához kell a using System.IO; sor, amelyet a 2.2 leckében már felvettél.
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. A feladatokhoz egy rtbDokumentum RichTextBox, egy sfdMentes SaveFileDialog és egy gomb kell. A fájl elejére tedd a using System.IO; sort, ha nincs ott. Csak a próbálkozás után nyisd le a megoldást.
Alap szint
1. Mentés RTF fájlba
A A btnMent gomb kérdezzen nevet, és mentse a dokumentumot RTF fájlba formázással együtt.Megoldás megnyitása
SaveFile a megadott fájlba írja a tartalmat. A RichTextBoxStreamType.RichText RTF formátumot jelent, a formázással együtt.private void btnMent_Click(object sender, EventArgs e)
{
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
if (sfdMentes.ShowDialog() == DialogResult.OK)
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
}
}
2. Kiterjesztés és alapnév
A mentés ablak alapból a dokumentum nevet kínálja fel, és ha a felhasználó kiterjesztés nélkül ír be nevet, a program tegye hozzá az A .rtf kiterjesztést.Megoldás megnyitása
FileName az alapértelmezett fájlnév, a DefaultExt az alapértelmezett kiterjesztés (pont nélkül), az AddExtension pedig igazra állítva automatikusan hozzáadja a hiányzó kiterjesztést.sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
sfdMentes.FileName = "dokumentum";
sfdMentes.DefaultExt = "rtf";
sfdMentes.AddExtension = true;
Közepes szint
3. Mentés sima szövegként
A szűrő kínálja az RTF és a TXT formátumot is. TXT választásakor csak a szöveg kerüljön a fájlba, formázás nélkül. A Megoldás megnyitása
FilterIndex megmondja, melyik szűrőt választotta a felhasználó (1-től számozva). Más megoldás: a fájl kiterjesztését vizsgáljuk. A TXT-hez a File.WriteAllText egyszerű szöveget ír.private void btnMent_Click(object sender, EventArgs e)
{
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf|Szöveges fájl (*.txt)|*.txt";
sfdMentes.AddExtension = true;
if (sfdMentes.ShowDialog() != DialogResult.OK)
{
return;
}
if (Path.GetExtension(sfdMentes.FileName).ToLower() == ".txt")
{
File.WriteAllText(sfdMentes.FileName, rtbDokumentum.Text);
}
else
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
}
}
4. Hibakezelés mentéskor
Védd a mentést Az try–catch blokkal: ha a fájl nem írható (például írásvédett mappa), a program mutasson érthető üzenetet, ne omoljon össze.Megoldás megnyitása
UnauthorizedAccessException jellemzően írásvédett helyre mentéskor keletkezik. A sikerüzenet a try blokk végén van, így hibánál nem jelenik meg.try
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
MessageBox.Show("A dokumentum mentve.");
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Ebbe a mappába nem menthetsz. Válassz másik helyet!");
}
catch (Exception ex)
{
MessageBox.Show("Nem sikerült menteni: " + ex.Message);
}
Kihívás szint
5. Üres dokumentum nem menthető
Ha a dokumentum teljesen üres, a program kérdezze meg: Üres dokumentumot mentesz. Folytatod? Csak Igen esetén jelenjen meg a mentés ablak. A kérdés a mentés ablak előtt jelenik meg. Nem esetén a Megoldás megnyitása
return kilép, így a felhasználónak nem kell feleslegesen nevet adnia.private void btnMent_Click(object sender, EventArgs e)
{
if (rtbDokumentum.Text.Length == 0)
{
DialogResult valasz = MessageBox.Show("Üres dokumentumot mentesz. Folytatod?", "Mentés", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (valasz == DialogResult.No)
{
return;
}
}
sfdMentes.Filter = "RTF dokumentum (*.rtf)|*.rtf";
sfdMentes.AddExtension = true;
if (sfdMentes.ShowDialog() == DialogResult.OK)
{
rtbDokumentum.SaveFile(sfdMentes.FileName, RichTextBoxStreamType.RichText);
}
}
6. Mentés–megnyitás ellenőrzése
Készíts egy gombot, amely a dokumentumot elmenti egy ideiglenes RTF fájlba, betölti egy második, rejtett Az ideiglenes fájl útvonalát a rtbEllenor RichTextBoxba, és összehasonlítja a két szöveget. Írja ki, hogy a mentés hibátlan volt-e.Megoldás megnyitása
Path.GetTempFileName() adja. A két Text összehasonlítása megmutatja, hogy a szöveg ugyanaz maradt-e. A fájlt a finally blokkban töröljük: az akkor is lefut, ha közben hiba történt. A formázás megmaradását így nem ellenőrizzük, csak a szöveget.private void btnEllenorzes_Click(object sender, EventArgs e)
{
string ideiglenes = Path.GetTempFileName();
try
{
rtbDokumentum.SaveFile(ideiglenes, RichTextBoxStreamType.RichText);
rtbEllenor.LoadFile(ideiglenes, RichTextBoxStreamType.RichText);
if (rtbDokumentum.Text == rtbEllenor.Text)
{
MessageBox.Show("A mentés hibátlan.");
}
else
{
MessageBox.Show("Eltérés van a mentett és az eredeti szöveg között!");
}
}
catch (Exception ex)
{
MessageBox.Show("Hiba az ellenőrzésnél: " + ex.Message);
}
finally
{
File.Delete(ideiglenes);
}
}
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. A A szövegdoboz tartalmát a megadott fájlba írja, a megadott formátumban. Azt, hogy a program RTF formátumban ment, a formázással együtt. PlainText esetén csak a nyers szöveg kerülne a fájlba. Hogy Mégse gomb esetén ne próbáljon a program fájlt menteni. Hogy a gomb és később a File menü is ugyanazt a kódot hívhassa, ne kelljen kétszer megírni. Elmented a dokumentumot, majd újra megnyitod, és ellenőrzöd, hogy ugyanazt a tartalmat és formázást kapod-e.1. Melyik két tulajdonság gondoskodik róla, hogy a fájl végén ott legyen a .rtf?
DefaultExt (rtf) és az AddExtension (true).2. Mit csinál a SaveFile?
3. Mit jelent a RichTextBoxStreamType.RichText mentéskor?
4. Miért kell ellenőrizni a ShowDialog() eredményét?
5. Miért tettük a mentési kódot külön Mentes() metódusba?
6. Mi az újranyitási teszt?
Mit tudsz már?
- Elhelyezel és beállítasz egy SaveFileDialog komponenst.
- Gondoskodsz róla, hogy a mentett fájl kiterjesztése .rtf legyen.
- A SaveFile metódussal formázással együtt mentesz.
- Védekezel a mentési hibák ellen try–catch szerkezettel.
- Tudod, hogy az RTF szöveges fájl, benne formázási kódokkal.
- Elvégzed az újranyitási tesztet.
Következő lecke: félkövér, dőlt, aláhúzott
A MiniWord már nyit és ment. Most végre megtanítjuk formázni is: kijelölt szöveget félkövérré, dőlttté és aláhúzottá tenni.






