Lépések:

Fájl létrehozásához:
    1. FileStream fs = new FileStream("filenev.txt", FileMode.Create);
(vagy)
Fájl hozzáíráshoz:
    1. FileStream fs = new FileStream("filenev.txt", FileMode.Append);
(Ha a feladat más fájlformátumot kér, akkor ne txt-be ments!)

Fájl kezelés értelmezése:
    2. StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);

(Innentől az sw-vel kezeljük a file-t: pl.: sw.WriteLine("Sorszöveg"))
(Ez maga a köztes rész, itt kell kezelni mindent ami a file-hoz tartozik)

StreamWriter bezárása:
    3. sw.Close();
FileStream bezárása:
    4. fs.Close();
                        
FileStream fs = new FileStream("filenev.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);

sw.WriteLine("nev;osztaly;atlag"); // iskola tanulóinak az átlagának mentése
// ez egy felső címsort (fejlécet) csinál, ami feladattól függ, hogy kéri-e

for (int i = 0; i < tanulok.Count; i++)
{
    sw.WriteLine($"{tanulok[i].Nev};{tanulok[i].Osztaly};{tanulok[i].Atlag}");
    // Egy előre megadott tanulok osztály listával dolgozik, ahol minden tanulot felír a txt fájlba
    // Magyarul megadjuk ; jelek elé és közé a tartalmat, amit ki akarunk íratni
}

sw.Close();
fs.Close();
Listába való beolvasás:
Lépések:

Fájl beolvasása:
    1. FileStream fs = new FileStream("filenev.txt", FileMode.Open);
(Ha a feladat más fájlformátumot kér, akkor ne txt-t nyiss meg!)

Fájl kezelés értelmezése:
    2. StreamReader sr = new StreamReader(fs, Encoding.UTF8);

(Innentől az sr-rel kezeljük a file-t: pl.: sr.ReadLine() => egy sor beolvasása a file-ból)
(Ez maga a köztes rész, itt kell kezelni mindent ami a file-hoz tartozik)

StreamReader bezárása:
    3. sr.Close();
FileStream bezárása:
    4. fs.Close();
Sor tartalmainak tárolása listában:
    string[] parts = sor.Split(';');

Tartalom különszedése listán belül:
    string[] innerparts = parts[Tartalom_indexe].Split('.');
Így mostmár hozzá tudunk rendelni az adott részhez: pl.: Convert.ToInt32(innerparts[0])
List tanulok = new List(); // Tanulo osztályú lista létrehozása
// Ez a lista az alábbiakat kéri: név;osztály;átlag;születési_év;születési_hónap;születési_nap
// Viszont a txt mondjuk nem szedi külön az évet, hónapot napot, hanem egyben írja .-tal elválasztva

FileStream fs = new FileStream("filenev.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);

// Amennyiben van fejléc (első soros címsor) be kell olvasni az első sort
sr.ReadLine();

while (!sr.EndOfStream) // Amíg a txt végére nem ér
{
    string sor = sr.ReadLine();
    string[] parts = sor.Split(';');
    string[] innerparts = parts[3].Split('.');
    tanulok.Add(new Tanulo
        (parts[0], 
        Convert.ToInt32(parts[1]), 
        Convert.ToInt32(parts[2]), 
        Convert.ToInt32(innerparts[0]),
        Convert.ToInt32(innerparts[1]),
        Convert.ToInt32(innerparts[2])));
}

sr.Close();
fs.Close();
Dictionary felépítése:
    Dictionary<kulcs_típus, érték_típus> dictionary_név = new Dictionary<megadott_kulcs_típus, mmegadott_érték_típus>();
Fentebb egy kulcsból és értékből álló adatszerkezetet hozunk létre => a kulcs és érték típusa a lényeg, amit mi adunk meg, hogy milyen változóként szeretnénk rögzíteni.

Pl: Ha számokhoz szeretnénk szövegeket rendelni, akkor: 
Dictionary<int, string> kulcs_szoveg = new Dictionary<int, string>();

Innentől már tudunk hozzájuk adni értékeket, pl.: kulcs_szoveg.Add(5, "legjobb jegy");

Dictionary végigjárása:
    foreach (var item in kulcs_szoveg)
    {
        Console.WriteLine($"Kulcs: {item.Key}");
        Console.WriteLine($"Érték: {item.Value}");
    }
Fenti példa végigjárja a Dictionary-t és kiíratja mindegyik kulcsát, majd értékét.
List tanulok = new List();Dictionary kodpar = new Dictionary();

kodpar.Add(1, "legrosszabb jegy");
kodpar.Add(2, "elégséges");
kodpar.Add(3, "közepes");
kodpar.Add(4, "jó");
kodpar.Add(5, "legjobb jegy");
            

foreach (var item in kodpar)
{
    Console.WriteLine($"Érdemjegy: {item.Key}");
    Console.WriteLine($"Érdemjegy értéke: {item.Value}");
}
DLL importálása:

Solution Explorer => References (jobb klikk) => Add References… => mysql.data.dll fájl kiválasztása => Add => A Reference Manager-en belül kipipálni a mysql.data.dll.t => OK
    => Innentől minden .cs file-ban, ahol használjuk a függvényt importálni kell a kód tetejére: 
            using MySql.Data.MySqlClient;

Kapcsolat megvalósítása:

Kapcsolat megvalósítása:
    1. Egy osztály, amely segítségével az sql részt szeretnénk megvalósítani
    2. Deklarálni kell egy MySqlConnection típusú mezőt, amellyel kapcsolatot tudunk megvalósítani
    3. Konstruktor, amely paraméterként a következő adatokat kapja meg:
        a. host = SQL szerver
        b. dbname = annak az adatbázisnak a neve, amelyet majd kezelni szeretnénk
        c. ui = felhasználónév az adatbázishoz
        d. pw = jelszó az adatbázishoz

class DBConnect
{
    private MySqlConnection con;
    public DBConnect (string host, string dbname, string ui, string pw)
    {
    	con = new MySqlConnection($"Database = {dbname}; Data Source = {host}; User Id = {ui}; Password = {pw};");
    }
}
Ha az osztály példányosítása megtörtént, már rendelkezünk a megfelelő adatokkal a kapcsolatok létrehozásához. 
Ezen adatokkal létrehozhatjuk az adatbázis kapcsolathoz szükséges függvényeket. 

Az egyik függvény a kapcsolat létrehozására hivatott (Connect()), 
míg a másik a megszüntetésére hivatott (ConnectClose()).
private bool Connect()
{
 	try{
 		con.Open();
 		return true;
 	} catch (Exception) 
 	{
 		return false;
 	}
}


private bool ConnectClose()
{
 	try{
 		con.Close();
 		return true;
 	} catch (Exception) 
 	{
 		return false;
 	}
}
Mi az SQL Injection?
A kód injektálás egyik leggyakoribb alkalmazása. Maga a kód injektálás az az eljárás, mikor egy olyam memóriatartományra, amely normal esetben adatot tartalmaz, illetőleg adatbevitel számára van fenntartva, valamely futtató környezet által futtatható ködot helyezünk el. Abban az esetben, ha az alkalmazás (vagy érintett rendszer) nem ellenőrzi az adott tartalmat akár az input idején akár a feldolgozást megelőzően, az adott kód lefut és segítségével hozzáférést szerezhet egy támadó az egyébként normal esetben nem elérhető erőforrásokhoz.

Fontos: minden olyan esetben, amikor olyan adatokkal szeretnénk dolgozni, amelyeket a felhasználó ad meg valamilyen formában, azoknál ezzel a módszerrel használjuk fel az adatokat.

Lenti példa: Bemutatja, hogy a nev és kor oszlopnak, hogyan tudunk saját paramétereket megadva értékeket beszúrni.
                Paraméter megadása: 
                    cmd.Parameters.AddWithValue("@nev", ÁLTALAD MEGADOTT NÉV);
                    cmd.Parameters.AddWithValue("@kor", ÁLTALAD MEGADOTT KOR);
public void InsertData(TesztOsztaly temp)
{
	if(Connect())
	{
		string query = "INSERT INTO teszttabla(nev, kor) VALUES(@nev, @kor);";
 		MySqlCommand cmd = new MySqlCommand(query, con);
 		cmd.Parameters.AddWithValue("@nev", temp.Nev);
 		cmd.Parameters.AddWithValue("@kor", temp.Kor);

 		cmd.ExecuteNonQuery();
 		ConnectClose();
	}
}
Lenti példa:    Sima MySql SELECT lekérdezés, ahol az adatokat egy TesztOsztaly listába tároljuk a megadott változók szerint adatlekérő metódust alkalmazva.
                Azaz amilyen adatot várunk, olyan adatlekérő metódust használunk.
Fő adatlekérő metódusok:
    GetString(index)
    GetDouble(index)
    GetBoolean(index)
    GetDateTime(index)
    GetInt32(index)
    GetDecimal(index)
    GetValue(index)
    IsDBNull(index)

public List SelectAll()
{
	List<TesztOsztaly> adatok = new List<TesztOsztaly>();
	if(Connect())
	{
		string query = "SELECT * FROM teszttabla;";
 		MySqlCommand cmd =  new MySqlCommand(query, con);
 		MySqlDataReader reader = cmd.ExecuteReader();
 		while(reader.Read())
 		{
 			adatok.Add(new TesztOsztaly(
                reader.GetInt32(0),
                reader.GetString(1),
                reader.GetInt32(2)
            ));
 		}
 		ConnectClose();
	}
 	return adatok;
}
Lenti példa: Ugyanúgy egy SELECT lekérdezés, de mivel itt csak egyetlen adatot (a táblázat kor-ainak átlagát) várunk, ezért csak szimplán át kell konvertálni, hogy megfeleljen az adott változónak, ahová menteni szeretnénk.
public double AtlagKor()
{
	double AvgAge = 0;
	if(Connect())
	{
		string query = "SELECT AVG(kor) FROM teszttabla;";
		MySqlCommand cmd = new MySqlCommand(query, con);
		if(cmd.ExecuteScalar() != null)
		{
			AvgAge = Convert.ToDouble(cmd.ExecuteScalar());
		}
		ConnectClose();
	}
	return AvgAge;
}
    
Példa 2:
.xaml.cs:

private void Hirdetesek(object sender, RoutedEventArgs e)
{
    List<Seller> sellers = getSellers();

    Seller selectedSeller = (Seller)List.SelectedItem;
    string selectedName = selectedSeller.Name;

    DBConnect db = new DBConnect("127.0.0.1", "ingatlan", "root", "");
    int hirdetesdb = Convert.ToInt32(db.HirdetesDb(selectedName));

    hirdetesek.Content = hirdetesdb;
}

Mysql meghívás class-ból:

public int HirdetesDb(string nev)
{
    int hirdetesdb = 0;
    if (Connect())
    {
        string query = $"SELECT COUNT(sellers.name) FROM sellers INNER JOIN realestates ON (sellers.id = realestates.sellerId) WHERE sellers.name = @nev;";
        MySqlCommand cmd = new MySqlCommand(query, con);
        cmd.Parameters.AddWithValue("@nev", nev);
        if (cmd.ExecuteScalar() != null)
        {
            hirdetesdb = Convert.ToInt32(cmd.ExecuteScalar());
        }
        ConnectClose();
    }
    return hirdetesdb;
}
Lenti példa:    - Létrehozunk egy DBConnect osztályú (korábban létrehozott) változót, aminek megadjuk a MySql elérési útját
                - Lefuttatjuk a korábban létrehozott InsertData függvényt a db változón és 
                  paraméterül adjuk a feltölteni kívánt adatokat.
DBConnect db = new DBConnect("127.0.0.1", "teszt", "root", "");
db.InsertData(new TesztOsztaly("István", 18));
- Ős / szülő osztály: Az az osztály, amelyet származtatunk és amit a származtatás során kiegészítünk.
- Gyerek / származtatott osztály: Az az osztály, ami az ős kiegészítésével jön létre.

Öröklődésnél átvesszük az ős osztály mezőit, metódusait, emellett lehetőségünk van a továbbiakban új mezőkkel, metódusokkal kiegészíteni. Fontos: metódusokat, adattagokat hozzáadni és módosítani tudunk, de eldobni belőle nem. Tehát a gyerek osztály mindent tud, amit az ős osztály.

C# esetén minden osztály csak egy ősosztállyal rendelkezhet.

Láthatóságok:
- private
- public
- protected - Csak az ős és a származtatott osztály férhet hozzá.

Öröklődés során minden mező automatikusan megtartja az ősosztálybeli jelentését. Ekkor az ős publikus mezői a gyerek osztályban is publikus mezők és a protected mezők a gyerek osztályban is protectedek lesznek.

Az ős private mezői a gyerek osztályban sem lesznek elérhetőek ezáltal.

Amikor a gyerek osztályt deklaráljuk, meg kell adni, hogy kit tekintsen ős osztálynak.

Base:

A base kulcsszó a konstruktornál arra hivatott, hogy az ős osztály paraméteres konstruktorára mutasson rá, ugyanis ott már az értékadás meg van írva, így a gyerek esetén nem kell még egyszer definiálnunk. (:base (adat))

New:

A new kulcsszó használata a gyerek osztály metódusa előtt, jelzi, hogy ez a metódus elrejti az alap osztály metódusát. Ez azért fontos, mert így a fordító tudja, hogy a gyerek osztály metódusa nem az alap osztály metódusának felülírása, hanem egy új metódus, amely elrejti az alap osztály metódusát.

Leegyszerűsítve példával:

Ember (Ős): - Ez a kiindiluó ősosztály, amihez hozzákötjük a Gyerek és Felnőtt osztályt (hisz egy gyerek és felnőtt ugyanúgy Ember) - Ezáltal, ha például a Labak() függvényt meghívjuk a programon belül egy Gyerek vagy Felnőtt osztállyal rendelkezővel, úgy azok ugyanúgy 2 lábúak lesznek - Valamint így nem kell külön a Gyerek és Felnőtt osztálynak is nevet megadni. - protected string Név { get => név; set => név = value; } - protected, hogy az ősosztály neve csak a gyerekosztályokban legyen elérhető Gyerek : Ember (Gyerek): && Felnőtt : Ember (Gyerek): - Származtatott gyerekosztályok - Külön függvényeket lehet megadni nekik, amit csak a saját osztályukban tudnak használni. - Azaz egy gyerek csak Iszik(), egy felnőtt pedig csak Drogozik(). - Programon belül lehet őket létrehozni a Felnőtt vagy Gyerek osztály előtaggal. - public Gyerek(string név) : base(név) { } - Alapjáraton üres, mert csak az származtatott név változót akarjuk tárolni - public Gyerek(string név) után kell egy : base(név) => feltüntetni, hogy honnan örökölje a nevet - Ide lehetne plusz változókat hozzáadni - Ehhez a Gyerek(string név) + {} állományt kell kiegészíteni - Példa változó hozzáadásához: public Gyerek(string név, bool iskolas) : base(név) { this.Iskolas = iskolas; }
class Ember
{
    private string név;

    public Ember(string név)
    {
        this.Név = név;
    }

    protected string Név { get => név; set => név = value; }
    public string Labak()
    {
        return Név + "-nak/nek 2 lába van (jobb esetben)";
    }
}
class Gyerek : Ember
{
    public Gyerek(string név) : base(név)
    {
    }
    public string Iszik()
    {
        return Név + " gyerek, kubut iszik.";
    }
}
class Felnőtt : Ember
{
    public Felnőtt(string név) : base(név)
    {
    }
    public string Drogozik()
    {
        return Név + " felnőtt, szétdrogozza magát.";
    }
}
internal class Program
{
    static void Main(string[] args)
    {
        Gyerek gyerek = new Gyerek("Ádám");
        Felnőtt felnőtt = new Felnőtt("Béla");

        Console.WriteLine("Ádám:");
        Console.WriteLine(gyerek.Labak());
        Console.WriteLine(gyerek.Iszik());

        Console.WriteLine("Béla:");
        Console.WriteLine(felnőtt.Labak());
        Console.WriteLine(felnőtt.Drogozik());
    }
}
- minden absztrakt osztálynak van legalább egy absztrakt metódusa (amihez nem tartozik megvalósítás)
- az absztrakt osztály nem példányosítható (mivel van egy absztrakt metódusa, s annak hívása futási hibával járna)
- a gyerekosztályban az absztrakt metódust kötelező felüldefiniálni, vagy a származtatott osztály is absztrakt osztály kell legyen
- absztrakt osztályból képzett származtatási lánc alján léteznie kell egy teljesen megvalósított osztálydefiníciónak
- A class szó elé kell tennünk az abstract kulcsszót, ezzel jelezve, hogy az egy absztrakt osztály lesz
- Az absztrakt metódus definiálásánál is kell az abstract kulcsszó:
- láthatóság abstract típus metódusnév(paraméterek);
- nincs metódustörzs, sőt még {} sem!
- ;-vel zárjuk!
- a származtatott osztályban a felüldefiniálás az override kulcsszóval történik

abstract class Ember
{
    private string név;

    public Ember(string név)
    {
        this.Név = név;
    }

    protected string Név { get => név; set => név = value; }
    public abstract string Mozog(); //Jelöltem, hogy absztrakt metódus, nincs megvalósítás
}
class Gyerek : Ember
{
    public Gyerek(string név) : base(név)
    {
    }
    public override string Mozog()
    {
        return Név + " gyerek kúszik-mászik, futkározik.";
    }
}
class Felnőtt : Ember
{
    public Felnőtt(string név) : base(név)
    {
    }
    public override string Mozog()
    {
        return Név + " felnőtt ember sétál.";
    }
}
internal class Program
{
    static void Main(string[] args)
    {
        //Ember ember = new Ember("Cili");
        //Nem példányosítható, mivel absztrakt

        Gyerek gyerek = new Gyerek("Ádám");
        Felnőtt felnőtt = new Felnőtt("Béla");

        Console.WriteLine(gyerek.Mozog());
        Console.WriteLine(felnőtt.Mozog());
    }
}
Lenti példa: 
    - Fő Grid-en belül lehet sorokra (RowDefinitions) és oszlopokra (ColumnDefinitions) bontva kialakítani
        - segít abban, hogy széthúzásnál-összehúzásnál is ugyanúgy jelenjen meg a content
    - Első <Grid.ColumnDefinitions> résznél a benne megadott <ColumnDefinition/> új oszlopokat csinál
        - Az oszlopoknak szélességi arányát Width="SZÁM*" lehet megadni
        - Ez ugyanúgy megoldható ugye sorokkal is, csak a Column helyett Row-t használunk, a Width helyett pedig Height-t.
    - Ha egy adott soron vagy oszlopon belül akarunk dolgozni, esetleg azon belüli új grid rendszereket létrehozni, 
      akkor azt a <Grid Grid.Column="0"> megadásával lehet biztosítani.
    - Ha azt akarjuk megadni, hogy a kontent melyik sorban/oszlopban jelenjen meg, akkor azt a 
      Grid.Column="SZÁM"/> vagy Grid.Row="SZÁM"/> lehet megadni.
        - Hogyha azt akarjuk, hogy a másik sorba/oszlopba is átlógjon az adott elem, akkor a 
          Grid.ColumnSpan="SZÁM(Hány oszlopba lógjon át)"/> Grid.RowSpan="SZÁM(Hány sorba lógjon át)"/> teszi ezt lehetővé
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="4*"/>
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="0">
        <ListBox Margin="10,10,10,10"/>
    </Grid>

    <Grid Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Label Content="Eladó neve:" HorizontalAlignment="Stretch" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Column="0"/>
        <Label Content="" Margin="10,10,10,0" VerticalAlignment="Top" Grid.Column="1"/>
        <Button Content="Button" Margin="10,63,20,0" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="2"/>

    </Grid>

</Grid>
Lenti példa:    - Ha már definiálva van a Lista, amit hozzá akarunk adni a WPF listatartományhoz, akkor a
                   List(wpf listanév).ItemsSource = LISTANÉV feldolgozza a Lista osztályt.
                   Ugyanezen az alapon működik a táblázat feltöltése is (pl.: Tabla.ItemsSource = CLASSLISTA_NEVE;)
                   Mivel egy osztály listáról van szó, ezért ki kell választani, hogy mit akarunk belőle megjeleníteni
                     Ehhez a List(wpf listanév).DisplayMemberPath = Osztályváltozó_neve szükséges
                     Például a List.DisplayMemberPath = "Name"; itt csak az osztálylista neveit jeleníti meg a wpf listában.
                    
                - Hogyha egy content-et (például label-nek) a kiválasztott lista eleméhez tartozó osztálybeli változójával szeretnénk megjeleníteni:
                    XAML Label-ön belül megadjuk: Content="{Binding ElementName=LISTANÉV, Path=SelectedItem.OSZTÁLYVÁLTOZÓ}"
                        Így automatikusan hozzárendeli a kiválasztott listaelemhez tartozó másik változó értékét (példában ez a telefonszám)
.xaml.cs:

public MainWindow()
{
    InitializeComponent();
    Listafeltolt();
}

private List<Seller> getSellers()
{
    DBConnect db = new DBConnect("127.0.0.1", "ingatlan", "root", "");
    List<Seller> sellers = db.SelectAll();

    return sellers;
}

private void Listafeltolt()
{
    List<Seller> sellers = getSellers();

    List.ItemsSource = sellers;
    List.DisplayMemberPath = "Name";
    //List.DisplayMemberPath = "Phone";
}

.xaml:

<Label x:Name="telo" Content="{Binding ElementName=List, Path=SelectedItem.Phone}" Margin="10,41,10,0" VerticalAlignment="Top" Grid.Column="1" Height="26"/>

CheckBox és RadioButton beszúrása: 
    <Groupbox><WrapPanel><CheckBox></CheckBox></WrapPanel></Groupbox>
    <Groupbox><WrapPanel><RadioButton></RadioButton></WrapPanel></Groupbox>
.xaml felépítése:

<Grid>
    <GroupBox Header="Neme" Margin="32,25,600,217" FontSize="36">
        <WrapPanel Margin="0,0,16,0" Orientation="Vertical">
            <RadioButton x:Name="r1" Content="Férfi"/>
            <RadioButton x:Name="r2" Content="Nő"/>
        </WrapPanel>
    </GroupBox>
    <GroupBox Header="Kedvenc szín" Margin="32,217,600,73" FontSize="24">
        <WrapPanel Margin="0,0,16,0" Orientation="Vertical">
            <CheckBox x:Name="cb1" Content="Kék"/>
            <CheckBox x:Name="cb2" Content="Rózsaszín"/>
        </WrapPanel>
    </GroupBox>
    <Button Content="Mentés" HorizontalAlignment="Left" Margin="306,93,0,0" VerticalAlignment="Top" FontSize="72" Height="243" Width="338" Click="mentes"/>
</Grid>

.xaml.cs felépítése:

private void mentes(object sender, RoutedEventArgs e)
{
    string eredmeny = string.Empty;

    if ((bool)r1.IsChecked)
    {
        eredmeny += "Neme: " + r1.Content; // Férfi
    }
    else
    {
        eredmeny += "Neme: " + r2.Content; // Nő
    }
    eredmeny += " Kedvenc szín: ";

    //Checkbox

    if ((bool)cb1.IsChecked)
    {
        eredmeny += cb1.Content; // Kék
    }
    if((bool)cb2.IsChecked)
    {
        eredmeny += cb2.Content; // Rózsaszín
    }
    MessageBox.Show(eredmeny, "Kijelölve", MessageBoxButton.OK, MessageBoxImage.Information);
}
                        
OpenFileDialog()
- A segítségével a felhasználó egy felugró ablakban (megnyitás ablak) böngészhet a számítógépen található fájlok között és kiválaszthat egyet, amit a program használhat. (pl.: megnyithat vagy feldolgozhat)

- Például egy gombra kattintáskor kiválasztunk egy txt fájlt.
- Először létre kell hoznunk egy OpenFileDialog példányt, ez az objektum fogja kezelni a fájl kiválasztásához szükséges beállításokat és műveleteket.
- Ezután be kell állítanunk a title és filter tulajdonságokat.
	Title: Beállíthatod az ablak címét, hogy a felhasználó tudja, miért nyílik meg (pl.: Válassz egy fájlt)
	Filter: Ezzel meghatározhatjuk, hogy mely fájltípusok jelenjenek meg. Ha csak szöveges fájlokat akarsz megjeleníteni, beállíthatod, hogy csak azokat lássa a felhasználó.

OpenFileDialog open = new OpenFileDialog();
open.Title = "Válasszon egy fájlt";
open.Filter = "Szöveges  fájlok (*.txt)|*.txt;

Filter felépítése
A filter string párokból áll, ahol az első része a leírás (amit a felhasználó lát), a második pedig a tényleges fájlkiterjesztés mintája. A leírás és a kiterjesztés között a (pipe: altgr + w) karaktert használjuk. Több szűrőpárt egymástól is | jellel választunk el.

„Szöveges fájlok (*.txt) | *.txt | Minden fájl | *.*”
„Kép fájlok (*.jpg, *.png) | *.jpg; *.png”

Megnyitás ellenőrzése
if(open.ShowDialog() == true)
{
	string utvonal = open.FileName;
	// Fájl beolvasása, vagy amit szeretnénk vele
}
else
{
	// Mi történjen, ha a Mégse gombra nyomott a felhasználó
}

A ShowDialog() metódus megnyitja a fájlkiválasztó ablakot és visszad egy bool értéket.
-	Ha true, a felhasználó a “Megnyitás” gombra kattintott és kiválasztott egy fájlt.
-	Ha false, a felhasználó a “Mégse” gombra kattintott vagy bezárta az ablakot.

A segítségével a felhasználó egy felugró ablakban (mentés másként ablak) menthet el egy fájlt. A felhasználó kiválaszthatja egy fájl nevét és a helyét, majd az alkalmazás az adott helyre menti az adatokat.
Először létre kell hoznunk belőle egy példányt.
-	Title
-	Filter
SaveFileDialog save = new SaveFileDialog();
// xaml.cs:
                            
private void BetoltesGomb_Click(object sender, RoutedEventArgs e)
{
    // 1. Létrehozzuk a fájlválasztó ablakot
    OpenFileDialog fajlValaszto = new OpenFileDialog();
    
    // 2. Beállítjuk az ablak tulajdonságait
    fajlValaszto.Title = "Válassz egy szöveges fájlt"; // Az ablak címe
    fajlValaszto.Filter = "Szöveges fájlok (*.txt)|*.txt|Minden fájl (*.*)|*.*";
    /*
     * Filter felépítése:
     * "Leírás|filt1;filt2|Leírás2|filt3"
     * Példák:
     * "Képek (*.jpg, *.png)|*.jpg;*.png"
     * "Excel fájlok (*.xlsx)|*.xlsx|CSV fájlok (*.csv)|*.csv"
     */

    // 3. Megnyitjuk a dialógusablakot és ellenőrizzük az eredményt
    if (fajlValaszto.ShowDialog() == true)
    {
        // Ha a felhasználó kiválasztott egy fájlt és OK-ra kattintott
        string kivalasztottFajl = fajlValaszto.FileName;
        
        try
        {
            // Fájl tartalmának beolvasása
            string tartalom = File.ReadAllText(kivalasztottFajl);
            FajlTartalmaTextBox.Text = tartalom;
            MessageBox.Show("Fájl sikeresen betöltve!", "Siker", MessageBoxButton.OK, MessageBoxImage.Information);
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Hiba történt a fájl betöltésekor: {ex.Message}", "Hiba", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
    else
    {
        // Ha a felhasználó mégsem választott fájlt vagy bezárta az ablakot
        MessageBox.Show("Nem választottál ki fájlt.", "Információ", MessageBoxButton.OK, MessageBoxImage.Information);
    }
}

private void MentesGomb_Click(object sender, RoutedEventArgs e)
{
    // 1. Létrehozzuk a mentés ablakot
    SaveFileDialog mentesAblak = new SaveFileDialog();
    
    // 2. Beállítjuk az ablak tulajdonságait
    mentesAblak.Title = "Fájl mentése másként";
    mentesAblak.Filter = "Szöveges fájlok (*.txt)|*.txt|Minden fájl (*.*)|*.*";
    mentesAblak.DefaultExt = ".txt"; // Alapértelmezett kiterjesztés
    mentesAblak.AddExtension = true; // Automatikusan hozzáadja a kiterjesztést ha a felhasználó nem írta be

    // 3. Megnyitjuk a dialógusablakot
    if (mentesAblak.ShowDialog() == true)
    {
        string celFajl = mentesAblak.FileName;
        
        try
        {
            // Szöveg mentése a kiválasztott fájlba
            File.WriteAllText(celFajl, FajlTartalmaTextBox.Text);
            MessageBox.Show("Fájl sikeresen elmentve!", "Siker", MessageBoxButton.OK, MessageBoxImage.Information);
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Hiba történt a fájl mentésekor: {ex.Message}", "Hiba", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}
<!-- XAML: -->

<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
    <!-- Gombok -->
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="0">
        <Button x:Name="BetoltesGomb" Content="Fájl betöltése" Margin="5" Padding="10,5" Click="BetoltesGomb_Click"/>
        <Button x:Name="MentesGomb" Content="Fájl mentése" Margin="5" Padding="10,5" Click="MentesGomb_Click"/>
    </StackPanel>
    
    <!-- Szövegdoboz a fájl tartalmának megjelenítéséhez -->
    <TextBox x:Name="FajlTartalmaTextBox" Grid.Row="1" Margin="5" 
             TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"/>
    
    <!-- Állapotsor -->
    <StatusBar Grid.Row="2">
        <StatusBarItem>
            <TextBlock>Kész</TextBlock>
        </StatusBarItem>
    </StatusBar>
</Grid>
Barnának:
//1. Feladat
    //Absztrakt osztály:
    //-> mindent tartalmazhat, amit egy normál osztály (tagváltozó, property, konstruktor,
    //  tagfüggvény, metódus)
    //-> tartalmaz absztrakt tagfüggvényt és/vagy metódus definíciót (kifejtés nélkül!!!):
    //  kifejtésük a származtatott (al) osztályban történik (nevük mindenhol ugyanaz, csak a
    //  funkciójuk más egy kicsit minden alosztályban)
    //-> nem példányosítható
    abstract class Auto
    {
        //tagváltozók
        //protected: származtatott (al) osztály látja őket, főprogram nem látja őket
        protected string rendszam, tipus;
        protected int megtettut;
        protected double fogyasztas;

        //konstruktor: a konkrét értékek paraméter listából jönnek
        //this: osztály tagváltozók
        protected Auto(string rendszam, string tipus, double fogyasztas, int megtettut)
        {
            this.rendszam = rendszam;
            this.tipus = tipus;
            this.fogyasztas = fogyasztas;
            this.megtettut = megtettut;
        }

        //Publikus property definíciók a tagváltozókból
        //Osztályon kívül (főprogramban) látható (olvasható), de nem módosítható (írható)
        public string Rendszam { get => rendszam; }
        public string Tipus { get => tipus; }
        public double Fogyasztas { get => fogyasztas; }
        public int Megtettut { get => megtettut; }

        //ToString(): beépített C# tagfüggvény
        //override: felülírjuk működésében
        public override string ToString()
        {
            return $"A(z) {rendszam} rendszámú autó {tipus} típusú";
        }

        //absztrakt tagfüggvény ill. metódus definíciók
        public abstract void Szazalek(List<int> ertek);
        public abstract double Atlag();
    }
                        
Ha az első 2 sort(listát és conStr-t) is a public partial class Mainwindow : Window alá írod, akkor nem kell mindig létrehoznod újra és újra. 
List<className> lista = new List<className>();
string conStr = "server=localhost;user=root;database=databaseName;port3306;password=;charset=utf8";
                            
MySqlConnection con = new MySqlConnection(connStr);

try
{
    
    con.Open();
    string sql = "SELECT * from tableName;";
    MySqlCommand query = new MySqlCommand(sql, con);
    MySqlDataReader reader = query.ExecuteReader();

    while (reader.Read())
    {
        lista.Add(new className(Convert.ToInt32(reader[0]),
            Convert.ToInt32(reader[1]),
            Convert.ToInt32(reader[2]),
            Convert.ToString(reader[3]),
            Convert.ToString(reader[4]),
            Convert.ToInt32(reader[5])));
    }
    reader.Close();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Hiba");
}

con.Close();
dataGrid.ItemsSource = lista;
                        
SQL tábla kiírása txt fájlba
List<className> lista = new List<className>();
string conStr = "server=localhost;user=root;database=databaseName;port3306;password=;charset=utf8";
                            
StreamWriter ki = new StreamWriter("feleadatX.txt")
MySqlConnection con = new MySqlConnection(connStr);

try
{
    
    con.Open();
    string sql = "SELECT tablaOszlop1, tablaOszlop2 from tableName;";
    MySqlCommand query = new MySqlCommand(sql, con);
    MySqlDataReader reader = query.ExecuteReader();

    while (reader.Read())
    {
        ki.WriteLine(reader[0] + " " + reader[1]);
    }
    reader.Close();
    ki.close()
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Hiba");
}

con.Close();
dataGrid.ItemsSource = lista;          
Alap konzolos C#-hoz.

public class autok
    {
        public string marka, rendszam;
        public int kilometer;

        public autok(string adottsor)
        {
            marka = adottsor.Split(' ')[0];
            rendszam = adottsor.Split(' ')[1];
            kilometer = Convert.ToInt32(adottsor.Split(' ')[2]);
        }
    }

    internal class Program
    {
        List<autok>auto=new List<autok>();

        public Program()
        {
            feladat1();
        }

        public void feladat1()
        {
            StreamReader be = new StreamReader("autok.txt");
            do
            {
                auto.Add(new autok(be.ReadLine()));
            }
            while (!be.EndOfStream);
            be.Close();
            //for(int i = 0; i < esemeny.Count; i++)
            //{
            //    Console.WriteLine(auto[i].marka+" " + auto[i].rendszam+" " + auto[i].kilometer);
            //}
        }

        static void Main(string[] args)
        {
            Program p=new Program();
            Console.ReadKey();
            Console.WriteLine();
        }
    }               
Minden különböző elemet kiszed és kiír a listából

List<string> lista = new List<string>();
            foreach (var a in nagylista)
            {
                if (!lista.Contains(a.adat))
                {
                    lista.Add(a.adat);
                }
            }
            foreach (var a in lista)
            {
                Console.Write(a + " ");
            }           
A listát csökkenő sorrendbe rendezi
for(int i = 0; i < lista.Count-1; i++)
{
    for(int j = i + 1; j < lista.Count; j++)
        {
            if (lista[i].Pontok < lista[j].Pontok) {
                var listaAllat = lista[i];
                lista[i] = lista[j];
                lista[j] = listaAllat;
            }
        }
}