Grafikus C# – Windows Forms tanfolyam › 7.8 lecke Windows Forms · 7.8 lecke · fájl- és mappaválasztók A fájlok megnyitásához, mentéséhez és a mappák kiválasztásához a Windows kész párbeszédablakokat ad, amelyeket a felhasználók ismernek és szeretnek: nem kell saját fájlböngészőt írnod. A 2.2 és 2.3 leckében a OpenFileDialog, SaveFileDialog és FolderBrowserDialog
OpenFileDialog és SaveFileDialog alapjait már használtad a MiniWordben. Most a teljes tudásukat: a szűrők (Filter), a kezdőmappa és az utolsó mappa megjegyzése, a többes kijelölés, a felülírás-védelem, a FolderBrowserDialog, a különleges mappák és a hibák kezelése.
A lecke végére
- helyes szűrő-sztringet írsz (
Filter,FilterIndex), és kezeled a kiválasztott szűrőt; - beállítod a kezdőmappát, a címet, az ellenőrzéseket (
CheckFileExists), és megjegyzed az utolsó mappát; - többes kijelölést (
Multiselect,FileNames) és mentést felülírás-védelemmel (OverwritePrompt,DefaultExt) használsz; - a
FolderBrowserDialogsegítségével mappát választasz, és a különleges mappákat (SpecialFolder) használod; - a fájlok adatait a
FileInfoosztállyal olvasod, és olvasható méretet írsz ki; - kezeled a gyakori hibákat (
IOException,UnauthorizedAccessException, hibás szűrő).
Mielőtt elkezded
Ehhez a leckéhez a 2.2–2.3 lecke (OpenFileDialog, SaveFileDialog első használata), a 7.4 lecke (MessageBox) és az 5.6 lecke (Settings) szükséges. A fájlkezelés részleteit (File, Path, Directory) a 10. fejezet tárgyalja, itt csak a szükséges alapokat használjuk.
OpenFileDialog: fájl megnyitása
| Tulajdonság | Jelentése |
|---|---|
Filter | A fájltípus-szűrők: "Felirat|minta|Felirat|minta" alakban, páronként (például "Szövegfájlok (*.txt)|*.txt|Minden fájl (*.*)|*.*"). |
FilterIndex | Melyik szűrő van kiválasztva induláskor (1-től számozva!). A felhasználó választása után is kiolvasható. |
InitialDirectory | A kezdőmappa. |
FileName | Az alapértelmezett (majd a kiválasztott) fájl neve, teljes útvonallal OK után. |
Title | Az ablak címe. |
CheckFileExists, CheckPathExists | Csak létező fájlt (mappát) enged választani (alapból igaz). |
Multiselect, FileNames | Több fájl kijelölése; a kiválasztottak tömbje. |
RestoreDirectory | Az ablak bezárásakor visszaállítja az eredeti munkamappát (hasznos, ha a program relatív útvonalakat használ). |
private void miMegnyit_Click(object sender, EventArgs e)
{
using (OpenFileDialog ablak = new OpenFileDialog())
{
ablak.Title = "Dokumentum megnyitása";
ablak.Filter = "Szövegfájlok (*.txt)|*.txt|Rich Text (*.rtf)|*.rtf|Minden fájl (*.*)|*.*";
ablak.FilterIndex = 1; // az első szűrő (1-től indul!)
ablak.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
ablak.CheckFileExists = true;
ablak.Multiselect = false;
if (ablak.ShowDialog(this) != DialogResult.OK)
{
return; // Mégse: nincs teendő
}
string utvonal = ablak.FileName;
try
{
rtbSzoveg.Text = File.ReadAllText(utvonal);
tsslUzenet.Text = "Megnyitva: " + Path.GetFileName(utvonal);
}
catch (Exception ex)
{
MessageBox.Show(this, "A fájl nem nyitható meg." + Environment.NewLine + ex.Message, "Megnyitás", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}Filter szövege mindig páros számú részből áll (felirat és minta). Az utolsó pár után nincs |. A több minta pontosvesszővel (*.png;*.jpg) adható meg egy szűrőben.OpenFileDialog komponens az ablak components gyűjteményében van, és az ablakkal együtt szabadul fel. Kódból létrehozva using kell (7.5 lecke).OK után a FileName a fájl teljes útvonala (C:\Mappa\fajl.txt), a SafeFileName csak a neve. A mappa a Path.GetDirectoryName hívással kapható.OK eredménynél dolgozz a fájllal. A Cancel a felhasználó szándékos döntése, nem hiba.Jósolj!
A Filter értéke "Szöveg (*.txt)|*.txt|Képek" (az utolsó mintapár hiányzik). Mi történik a ShowDialog hívásakor?
Jóslat ellenőrzése
A hibás szűrő-sztring (páratlan számú rész) miatt a Filter beállítása vagy a ShowDialog ArgumentException kivételt dob (a szűrő nem érvényes). A hiba csak futáskor derül ki, ezért érdemes a szűrőt gondosan felépíteni (lásd a Gyakorlótárat), és egyszer kipróbálni.
SaveFileDialog: mentés
| Tulajdonság | Jelentése |
|---|---|
Filter, FilterIndex | Mint a megnyitásnál; a kiválasztott szűrő adja a javasolt kiterjesztést. |
FileName | A javasolt fájlnév (például a dokumentum jelenlegi neve). |
DefaultExt | A kiterjesztés (pont nélkül: "txt"), amelyet a rendszer hozzáfűz, ha a felhasználó nem ír. |
AddExtension | Hozzáadja-e a kiterjesztést (alapból igaz). |
OverwritePrompt | Létező fájl felülírása előtt rákérdez (alapból igaz). Hagyd bekapcsolva. |
CreatePrompt | Nem létező fájl létrehozása előtt kérdez (alapból hamis). |
private bool MentesMaskent()
{
using (SaveFileDialog ablak = new SaveFileDialog())
{
ablak.Title = "Mentés másként";
ablak.Filter = "Szövegfájlok (*.txt)|*.txt|Minden fájl (*.*)|*.*";
ablak.DefaultExt = "txt";
ablak.AddExtension = true;
ablak.OverwritePrompt = true;
ablak.FileName = fajl.Length == 0 ? "Névtelen" : Path.GetFileName(fajl);
if (fajl.Length > 0)
{
ablak.InitialDirectory = Path.GetDirectoryName(fajl); // a jelenlegi fájl mappája
}
if (ablak.ShowDialog(this) != DialogResult.OK)
{
return false;
}
try
{
File.WriteAllText(ablak.FileName, rtbSzoveg.Text);
fajl = ablak.FileName;
return true;
}
catch (Exception ex)
{
MessageBox.Show(this, "A mentés nem sikerült." + Environment.NewLine + ex.Message, "Mentés", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
}bool: a hívó (bezárás, új dokumentum) ebből tudja, folytathat-e (7.4 lecke).DefaultExt a .txt kiterjesztést automatikusan hozzáfűzi, ha a felhasználó nem ír. A kiválasztott szűrő is befolyásolja (a FilterIndex alapján).OverwritePrompt a rendszer saját kérdése: nem kell külön MessageBox. Ha az OverwritePrompt hamis, te vagy felelős az adatvesztésért.CheckPathExists alapján ellenőrzi (alapból igaz), de a fájl írásakor akkor is előfordulhat hiba (jogosultság, lemez telt), ezért a mentés try–catch védelmet kap.Jósolj!
A SaveFileDialog DefaultExt értéke "txt", a felhasználó a jegyzet nevet írja be, és az Összes fájl (*.*) szűrő van kiválasztva. Milyen néven jön létre a fájl?
Jóslat ellenőrzése
A jegyzet.txt (a DefaultExt hozzáfűzi, mert a felhasználó nem adott kiterjesztést). Ha a felhasználó jegyzet.doc nevet ír, azt a rendszer megtartja, nem írja át .txt kiterjesztésre: a kiterjesztés ellenőrzése a program dolga lehet.
FolderBrowserDialog: mappa választása
A FolderBrowserDialog mappát (nem fájlt) választ: másolás céljához, képek mappájához, adatmappához. Fontosabb tulajdonságai:
| Tulajdonság | Jelentése |
|---|---|
Description | A mappafa fölött megjelenő magyarázat. |
SelectedPath | A kezdetben kijelölt mappa, majd az OK után a választott mappa útvonala. |
RootFolder | A fa gyökere (Environment.SpecialFolder érték, például MyComputer, Desktop). |
ShowNewFolderButton | Megjelenjen-e az Új mappa gomb. |
private string MappaValaszt(string cim, string kezdo)
{
using (FolderBrowserDialog ablak = new FolderBrowserDialog())
{
ablak.Description = cim;
ablak.ShowNewFolderButton = true;
if (Directory.Exists(kezdo))
{
ablak.SelectedPath = kezdo; // az utolsó használt mappa kijelölve
}
return ablak.ShowDialog(this) == DialogResult.OK ? ablak.SelectedPath : null;
}
}
// használat: az utolsó mappa megjegyzése a Settings-ben (5.6 lecke)
string mappa = MappaValaszt("Válaszd ki a képek mappáját.", Properties.Settings.Default.UtolsoMappa);
if (mappa != null)
{
Properties.Settings.Default.UtolsoMappa = mappa;
Properties.Settings.Default.Save();
}Újabb .NET: modernabb mappaválasztó
A FolderBrowserDialog hagyományos, kicsit régies kinézetű (mappafa). Az újabb .NET-verziókban (a .NET 8 körül) megjelent egy modernebb, a fájlválasztóhoz hasonló mappaválasztó (OpenFolderDialog). Hogy a használt projekted támogatja-e, a verziótól függ: ellenőrizd az Eszköztárban és az IntelliSense-ben. A FolderBrowserDialog minden verzióban működik.
Jósolj!
A SelectedPath kezdőértéke egy már nem létező mappa (a felhasználó törölte). Mit csinál az ablak?
Jóslat ellenőrzése
A nem létező kezdőmappát a rendszer figyelmen kívül hagyja, és az ablak a gyökérnél (vagy az utolsó ismert helyen) nyílik meg, de a viselkedés verziófüggő lehet. Ezért a kezdőmappát előbb ellenőrizd (Directory.Exists), és csak létező értéket adj meg.
Különleges mappák, fájladatok, hibák
// különleges mappák: a felhasználó dokumentumai, asztala, az alkalmazásadatok
string dokumentumok = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string asztal = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string adat = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); // a program saját adatainak helye
// fájladatok
FileInfo info = new FileInfo(utvonal);
lblMeret.Text = Meret(info.Length); // bájtban
lblDatum.Text = info.LastWriteTime.ToString("yyyy. MM. dd. HH:mm");
// az olvasható méret
private string Meret(long bajt)
{
string[] egyseg = { "B", "KB", "MB", "GB" };
double ertek = bajt;
int i = 0;
while (ertek >= 1024 && i < egyseg.Length - 1)
{
ertek = ertek / 1024;
i++;
}
return ertek.ToString(i == 0 ? "0" : "0.#") + " " + egyseg[i];
}| Hiba | Mikor? | Üzenet a felhasználónak |
|---|---|---|
FileNotFoundException, DirectoryNotFoundException | A fájl időközben törlődött, vagy az útvonal érvénytelen. | „A fájl nem található. Lehet, hogy áthelyezték vagy törölték.” |
UnauthorizedAccessException | Nincs jogosultság (védett mappa, csak olvasható fájl). | „Nincs jogosultság a mentéshez. Válassz másik mappát.” |
IOException | A fájlt másik program használja, a lemez tele van. | „A fájl nem érhető el. Lehet, hogy másik program használja.” |
ArgumentException | Érvénytelen karakter az útvonalban, hibás szűrő. | „Az útvonal vagy a fájlnév érvénytelen.” |
MyDocuments. A program saját beállításai és adatai az ApplicationData alá való, nem a program mappájába (ott a felhasználónak nincs mindig írási joga).File.Exists vizsgálat után a fájl még törlődhet: a try–catch nélkülözhetetlen (13. fejezet).File.ReadAllText az egész fájlt a memóriába tölti. Néhány MB felett érdemes a méretet ellenőrizni, és figyelmeztetni a felhasználót (FileInfo.Length).Path.GetDirectoryName értékét tárold a Settings-ben.Jósolj!
A program a mentést a program saját mappájába végzi (C:\Program Files\...), a felhasználó pedig nem rendszergazda. Mi történik a mentéskor?
Jóslat ellenőrzése
UnauthorizedAccessException (nincs írási jog a védett mappában). A felhasználói adatokat a felhasználó mappáiba (MyDocuments, ApplicationData) kell menteni. Ezért fontos a SpecialFolder használata a fix útvonal helyett (14. fejezet).
Mit tegyél ide: a Mentés másként ablak a szűrőkkel (Szövegfájlok, Minden fájl) és az Új mappa gombbal.Javasolt fájlnév: winforms-7-8-ment.webp · Alt szöveg: A Mentés másként párbeszédablak
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. ArgumentException a Filter beállításakor
ofd.Filter = "Szöveg|*.txt|Képek"; // páratlan számú részHiba és javítás
A szűrő felirat–minta párokból áll: "Szöveg|*.txt|Képek|*.png;*.jpg".
2. A fájlt akkor is feldolgozza, ha a felhasználó a Mégse gombot nyomta
ofd.ShowDialog();
File.ReadAllText(ofd.FileName); // Mégse esetén üres a FileNameHiba és javítás
Vizsgáld az eredményt: if (ofd.ShowDialog(this) == DialogResult.OK) { ... }.
3. A mentett fájlnak nincs kiterjesztése
A felhasználó beír egy nevet, és a fájl kiterjesztés nélkül jön létre. A Ok és javítás
DefaultExt vagy az AddExtension nincs beállítva. Állítsd be a DefaultExt = "txt" értéket, és hagyd bekapcsolva az AddExtension tulajdonságot.
4. A felhasználó adatai elvesznek felülíráskor
A mentés csendben felülír egy meglévő fájlt. Az Ok és javítás
OverwritePrompt = false kikapcsolta a rendszer kérdését. Hagyd alapértéken (igaz), vagy kérdezz saját üzenettel.
5. A program mindig ugyanabban a mappában nyílik meg
A felhasználó az előző mappában szeretne folytatni. Az Ok és javítás
InitialDirectory fix. Tárold a legutóbbi mappát (Settings), és add át a megnyitás előtt (ellenőrizd, hogy létezik-e).
6. UnauthorizedAccessException a program mappájába mentve
A mentés a telepített program mappájában hibát ad. A program mappája védett. Használj felhasználói mappát: Ok és javítás
Environment.SpecialFolder.MyDocuments vagy ApplicationData.
Mini projekt: mappaböngésző
Készíts programot, amely egy kiválasztott mappa fájljait listázza és kezeli:
- Mappa: a Mappa kiválasztása... gomb
FolderBrowserDialog-ot nyit (aSettings-ben tárolt utolsó mappával kezdi); az útvonal egylblMappacímkében látszik. - Szűrő:
cmbSzuro(Minden fájl, Szövegek (*.txt;*.md), Képek (*.png;*.jpg;*.jpeg)), rendezés:cmbRendez(Név, Méret, Dátum). A lista (lstFajlok) a szűrő és a rendezés szerint frissül. - Részletek: a kijelölt fájlról a
lblReszletekmutatja a nevet, az olvasható méretet, a módosítás dátumát és az útvonalat. - Másolás: a Másolás ide... gomb a kijelölt fájlt egy másik mappába másolja (
FolderBrowserDialog); ha létezik ugyanolyan nevű fájl,YesNoüzenet kérdez (Button2a Nem). - Fájlok hozzáadása: az Egyedi fájlok... gomb
OpenFileDialog(Multiselect) segítségével további fájlokat tesz a listába, amely különlstEgyedilistában jelenik meg. - Lista mentése: a Lista mentése... gomb
SaveFileDialog-gal szövegfájlba menti a fájlok nevét és méretét. - Minden fájlművelet
try–catchvédelmet kap; a hibákra érthető üzenet jelenik meg, az állapotsor tájékoztat. - Teszteld: több mappa, minden szűrő és rendezés, nagy mappa, üres mappa, védett mappa (hiba), másolás meglévő fájlra (Igen/Nem), a lista mentése és megnyitása.
Megoldás megnyitása (próbáld ki előbb önállóan!)
A fájlok List<FileInfo> gyűjteménybe kerülnek, a rendezés a Sort metódus lambdájával történik. A szűrő mintái pontosvesszővel vannak elválasztva, minden mintára külön Directory.GetFiles hívás fut.
private string mappa = "";
private List<FileInfo> fajlok = new List<FileInfo>();
private readonly string[] mintak = { "*.*", "*.txt;*.md", "*.png;*.jpg;*.jpeg" };
private void Form1_Load(object sender, EventArgs e)
{
cmbSzuro.Items.AddRange(new object[] { "Minden fájl", "Szövegek (*.txt;*.md)", "Képek (*.png;*.jpg;*.jpeg)" });
cmbRendez.Items.AddRange(new object[] { "Név", "Méret", "Dátum" });
cmbSzuro.SelectedIndex = 0;
cmbRendez.SelectedIndex = 0;
string mentett = Properties.Settings.Default.UtolsoMappa;
if (Directory.Exists(mentett))
{
mappa = mentett;
Betolt();
}
}
private string MappaValaszt(string cim, string kezdo)
{
using (FolderBrowserDialog ablak = new FolderBrowserDialog())
{
ablak.Description = cim;
if (Directory.Exists(kezdo))
{
ablak.SelectedPath = kezdo;
}
return ablak.ShowDialog(this) == DialogResult.OK ? ablak.SelectedPath : null;
}
}
private void btnMappa_Click(object sender, EventArgs e)
{
string uj = MappaValaszt("Válaszd ki a böngészendő mappát.", mappa);
if (uj != null)
{
mappa = uj;
Properties.Settings.Default.UtolsoMappa = mappa;
Properties.Settings.Default.Save();
Betolt();
}
}
private void Betolt()
{
lblMappa.Text = mappa;
fajlok.Clear();
try
{
foreach (string minta in mintak[cmbSzuro.SelectedIndex].Split(';'))
{
foreach (string ut in Directory.GetFiles(mappa, minta, SearchOption.TopDirectoryOnly))
{
fajlok.Add(new FileInfo(ut));
}
}
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(this, "Ehhez a mappához nincs jogosultságod.", "Mappa", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (IOException ex)
{
MessageBox.Show(this, "A mappa nem olvasható: " + ex.Message, "Mappa", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Rendez();
}
private void Rendez()
{
switch (cmbRendez.SelectedIndex)
{
case 1:
fajlok.Sort((a, b) => b.Length.CompareTo(a.Length)); // a legnagyobb elöl
break;
case 2:
fajlok.Sort((a, b) => b.LastWriteTime.CompareTo(a.LastWriteTime)); // a legfrissebb elöl
break;
default:
fajlok.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase));
break;
}
lstFajlok.Items.Clear();
foreach (FileInfo f in fajlok)
{
lstFajlok.Items.Add(f.Name + " (" + Meret(f.Length) + ")");
}
tsslUzenet.Text = fajlok.Count + " fájl";
}
private void SzuroVagyRendez_Changed(object sender, EventArgs e)
{
if (mappa.Length == 0) { return; }
if (sender == cmbSzuro) { Betolt(); } else { Rendez(); }
}
private string Meret(long bajt)
{
string[] egyseg = { "B", "KB", "MB", "GB" };
double ertek = bajt;
int i = 0;
while (ertek >= 1024 && i < egyseg.Length - 1)
{
ertek = ertek / 1024;
i++;
}
return ertek.ToString(i == 0 ? "0" : "0.#") + " " + egyseg[i];
}
private void lstFajlok_SelectedIndexChanged(object sender, EventArgs e)
{
int i = lstFajlok.SelectedIndex;
if (i < 0)
{
lblReszletek.Text = "";
return;
}
FileInfo f = fajlok[i];
lblReszletek.Text = $"Név: {f.Name}{Environment.NewLine}Méret: {Meret(f.Length)}{Environment.NewLine}Módosítva: {f.LastWriteTime:yyyy. MM. dd. HH:mm}{Environment.NewLine}Útvonal: {f.FullName}";
}
private void btnMasol_Click(object sender, EventArgs e)
{
int i = lstFajlok.SelectedIndex;
if (i < 0) { return; }
string cel = MappaValaszt("Hova másolod a fájlt?", mappa);
if (cel == null) { return; }
string celUt = Path.Combine(cel, fajlok[i].Name);
if (File.Exists(celUt) && MessageBox.Show(this, "A célmappában már van ilyen nevű fájl. Felülírod?", "Másolás", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
{
return;
}
try
{
File.Copy(fajlok[i].FullName, celUt, true);
tsslUzenet.Text = "Másolva: " + celUt;
}
catch (Exception ex)
{
MessageBox.Show(this, "A másolás nem sikerült: " + ex.Message, "Másolás", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnEgyedi_Click(object sender, EventArgs e)
{
using (OpenFileDialog ablak = new OpenFileDialog())
{
ablak.Title = "Fájlok kiválasztása";
ablak.Filter = "Minden fájl (*.*)|*.*";
ablak.Multiselect = true;
if (Directory.Exists(mappa))
{
ablak.InitialDirectory = mappa;
}
if (ablak.ShowDialog(this) == DialogResult.OK)
{
foreach (string ut in ablak.FileNames)
{
lstEgyedi.Items.Add(ut);
}
}
}
}
private void btnListaMent_Click(object sender, EventArgs e)
{
using (SaveFileDialog ablak = new SaveFileDialog())
{
ablak.Filter = "Szövegfájlok (*.txt)|*.txt";
ablak.DefaultExt = "txt";
ablak.FileName = "fajllista";
if (ablak.ShowDialog(this) != DialogResult.OK) { return; }
List<string> sorok = new List<string>();
foreach (FileInfo f in fajlok)
{
sorok.Add(f.Name + ";" + f.Length);
}
try
{
File.WriteAllLines(ablak.FileName, sorok);
tsslUzenet.Text = "Lista mentve: " + ablak.FileName;
}
catch (Exception ex)
{
MessageBox.Show(this, "A lista mentése nem sikerült: " + ex.Message, "Mentés", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}Mit tegyél ide: a mappaböngésző a fájllistával, a részletekkel és a szűrő/rendezés választókkal.Javasolt fájlnév: winforms-7-8-kesz.webp · Alt szöveg: A mappaböngésző 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. Szűrő felépítése listából
Írj segédmetódust, amely egy típuslistából (Szöveg: txt, md; Kép: png, jpg) építi fel a Nincs pár- vagy elválasztóhiba. A metódus elejére tehetsz egy Minden támogatott szűrőt is.Filter szöveget, a pontos formátumban. Miért jobb a kézi írásnál?Egy lehetséges megoldás
private string SzuroEpit(string[] nevek, string[][] kiterjesztesek)
{
List<string> reszek = new List<string>();
for (int i = 0; i < nevek.Length; i++)
{
List<string> mintak = new List<string>();
foreach (string k in kiterjesztesek[i])
{
mintak.Add("*." + k);
}
string minta = string.Join(";", mintak);
reszek.Add(nevek[i] + " (" + minta + ")|" + minta);
}
reszek.Add("Minden fájl (*.*)|*.*");
return string.Join("|", reszek);
}
2. Mentés másként a szűrő szerinti kiterjesztéssel
A A SaveFileDialog szűrői: Szöveg (*.txt), Markdown (*.md). Mentés után ellenőrizd, hogy a fájl kiterjesztése megegyezik-e a választott szűrővel, és ha nem, egészítsd ki. Hogyan?Egy lehetséges megoldás
FilterIndex (1-től) alapján a kívánt kiterjesztés kiválasztható; a Path.ChangeExtension módosítja, ha a felhasználó mást írt (vagy kiegészíti, ha nincs).string[] kit = { ".txt", ".md" };
string ut = sfd.FileName;
string kivant = kit[sfd.FilterIndex - 1];
if (!Path.GetExtension(ut).Equals(kivant, StringComparison.OrdinalIgnoreCase))
{
ut = ut + kivant; // kiegészítés (nem cserélünk meglévő kiterjesztést)
}
3. Utolsó fájl megnyitása indításkor
A program induláskor megnyitja az utoljára használt fájlt (ha létezik). Hol tárolod az útvonalat, és mit teszel, ha a fájl közben eltűnt? A Egy lehetséges megoldás
Settings-ben (UtolsoFajl), a Load-ban megnyitva, File.Exists és try–catch védelemmel. Ha eltűnt, csendben kihagyja (az állapotsor jelezhet).private void Form1_Load(object sender, EventArgs e)
{
string ut = Properties.Settings.Default.UtolsoFajl;
if (ut.Length > 0 && File.Exists(ut))
{
try
{
rtbSzoveg.Text = File.ReadAllText(ut);
fajl = ut;
}
catch (IOException)
{
tsslUzenet.Text = "Az utolsó fájl nem nyitható meg.";
}
}
}
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. Filter
Írd meg a szűrő-sztringet: Képek (png, jpg), Minden fájl.Megoldás megnyitása
"Képek (*.png;*.jpg)|*.png;*.jpg|Minden fájl (*.*)|*.*". Négy rész: két felirat, két minta.
2. Eredmények
Mit ad a ShowDialog, ha a felhasználó a Mégse gombot nyomja? Mi a FileName értéke ilyenkor?Megoldás megnyitása
DialogResult.Cancel. A FileName az előző (vagy üres) érték, ezért nem szabad használni.
Közepes szint
3. Több fájl megnyitása
Egy A Multiselect ablak a kiválasztott fájlok neveit és méretét egy listába írja. Melyik tulajdonságot használod, és miért nem a FileName-et?Megoldás megnyitása
FileNames tömböt (az összes kiválasztott útvonal). A FileName csak az elsőt adja.foreach (string ut in ofd.FileNames)
{
FileInfo f = new FileInfo(ut);
lstFajlok.Items.Add(f.Name + " (" + f.Length + " bájt)");
}
4. Mentés a felhasználó mappájába
Készíts mentési útvonalat a Dokumentumok mappán belüli MiniProgram almappába. Mit kell megoldanod, ha az almappa még nincs meg? A Megoldás megnyitása
Directory.CreateDirectory létrehozza (ha már megvan, nem csinál semmit), a Path.Combine építi az útvonalat.string alap = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string mappa = Path.Combine(alap, "MiniProgram");
Directory.CreateDirectory(mappa); // létrehozza, ha hiányzik
File.WriteAllText(Path.Combine(mappa, "adat.txt"), tartalom);
Kihívás szint
5. Húzd és ejtsd fájl nyitásra
A szerkesztőbe húzott fájl megnyílik (Drag and Drop, 5.3 lecke). Hogyan olvasod ki a húzott fájlok útvonalát?Megoldás megnyitása
AllowDrop = true, a DragEnter eseményben a DataFormats.FileDrop ellenőrzése, a DragDrop eseményben GetData(DataFormats.FileDrop) a string[] tömb.private void Form1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None;
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] utak = (string[])e.Data.GetData(DataFormats.FileDrop);
if (utak.Length > 0)
{
Megnyit(utak[0]);
}
}
6. Biztonságos mentés ideiglenes fájllal
A mentés közben a program összeomlik: a fájl részben íródhat, és az eredeti elvész. Hogyan védekezel ideiglenes fájllal és átnevezéssel? Előbb egy ideiglenes fájlba írsz, és csak siker esetén cseréled az eredetit (Megoldás megnyitása
File.Replace vagy File.Move törlés után). Így az eredeti sosem marad félkész állapotban.private void BiztonsagosMent(string ut, string tartalom)
{
string ideiglenes = ut + ".tmp";
File.WriteAllText(ideiglenes, tartalom);
if (File.Exists(ut))
{
File.Delete(ut);
}
File.Move(ideiglenes, ut);
}
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. Felirat|minta párokban, 1-től. A kiterjesztést automatikusan hozzáfűzi a mentett fájlnévhez, ha a felhasználó nem ad meg. A felhasználó mappáiba ( A vizsgálat után a fájl még törlődhet vagy lezárulhat: a 1. Hogyan épül fel a Filter szöveg?
| jellel elválasztva; a több minta pontosvesszővel.2. Honnan számozódik a FilterIndex?
3. Mit ad a FileNames?
Multiselect esetén az összes kiválasztott fájl útvonalát.4. Mire való a DefaultExt?
5. Hová mentsd a felhasználói adatokat?
MyDocuments, ApplicationData), nem a program mappájába.6. Mik a leggyakoribb fájl-kivételek?
FileNotFoundException, UnauthorizedAccessException, IOException, ArgumentException.7. Miért nem elég a File.Exists?
try–catch kell.
Mit tudsz már?
- Szűrőt építesz, és az
OpenFileDialog,SaveFileDialog,FolderBrowserDialogbeállításait ismered. - Többes kijelölést és felülírás-védelmet használsz.
- Megjegyzed az utolsó mappát, és a különleges mappákat használod.
- A fájladatokat a
FileInfoosztállyal olvasod. - Érthetően kezeled a fájl- és mappahibákat.
Következő lecke: FontDialog és ColorDialog
A betűtípus- és színválasztó ablakok: alkalmazás a kijelölésre és az egész szövegre, mentés szövegként, és a kontraszt ellenőrzése.




