Sari la conținut
Atestia
Înapoi la proiecte

Proiectul de atestat

Proiect de atestat în C# cu Windows Forms: formulare, bază de date și executabilul care pornește la comisie

Cum faci un proiect de atestat la informatică în C# cu Windows Forms: ce alegi între .NET și .NET Framework, ce bază de date legi, interogări parametrizate, DataGridView, capcana cu Access pe 32 și 64 de biți, livrarea executabilului și întrebările comisiei.

12

minute de citit

16

secțiuni

8

întrebări frecvente

Actualizat pe , pe baza metodologiei oficiale.

Pe această pagină
  1. Pentru cine e potrivit
  2. Capcana numărul unu: o fereastră frumoasă fără date nu e o aplicație
  3. Prima decizie: .NET sau .NET Framework
  4. Ce bază de date legi
  5. Codul: o clasă pentru bază, evenimentele în formular
  6. Designerul: două fișiere, unul nu se atinge
  7. Interogarea care se notează
  8. Datele utilizatorului nu intră niciodată direct în SQL
  9. Capcana cu Access: 32 sau 64 de biți
  10. Cum ajunge aplicația pe calculatorul comisiei
  11. Planul pe luni
  12. Ce te întreabă comisia
  13. Greșeli frecvente
  14. Ce livrezi
  15. Întrebări frecvente
  16. De unde vin informațiile de aici

C# cu Windows Forms e una dintre cele mai directe căi spre o aplicație desktop care arată a aplicație: desenezi fereastra cu mouse-ul în Visual Studio, apoi scrii codul care rulează la fiecare click. Sintaxa e apropiată de C++, deci trecerea de la ce ai lucrat la clasă e mai scurtă decât pare.

Pagina asta e despre o aplicație desktop cu interfață desenată în designer, legată de o bază de date cu cel puțin trei tabele. Dacă preferi să scrii și interfața în cod, fără designer și fără Visual Studio, e proiectul în Python. Dacă vrei baza de date construită vizual, fără cod, e proiectul în Access. Dacă vrei aplicație în browser, e proiectul în PHP și MySQL.

Dacă încă alegi între tehnologii, pornește de la cum îți alegi tema de proiect. Cadrul general al examenului e în ghidul atestatului.

Pentru cine e potrivit

Un proiect în C# cu Windows Forms merge dacă:

  • vrei o fereastră cu meniuri, tabele și formulare fără să scrii layout-ul de mână;
  • ai lucrat în C++ și vrei un limbaj apropiat, în care diferența o fac clasele și evenimentele;
  • tema are entități care se leagă — pacienți și programări, elevi și note, produse și stocuri.

Nu merge dacă nu ai acces constant la un calculator cu Windows și Visual Studio — Windows Forms nu rulează pe macOS sau Linux. Nu merge nici pentru un site de prezentare; acolo e proiectul în HTML, CSS și JavaScript.

Capcana numărul unu: o fereastră frumoasă fără date nu e o aplicație

Designerul face ușor să ai zece butoane și trei taburi în prima seară. Asta nu e un proiect, ci o machetă.

Nivel Ce conține Cum e primit
Ferestre cu butoane, fără date salvate Machetă Insuficient
Un formular care salvează într-un fișier text Interfață, fără model de date Minim acceptabil
Formulare + bază de date cu 3–4 tabele legate, DataGridView, interogări cu JOIN și agregare Aplicație reală Ținta
Plus căutare, editare, validări, rapoarte tipăribile Aplicație închegată Peste așteptări

Ținta e rândul al treilea. Peste el treci doar dacă îți rămâne timp după documentație.

Prima decizie: .NET sau .NET Framework

La New Project, Visual Studio îți oferă două șabloane cu nume aproape identice:

Șablon Ce e Când îl alegi
Windows Forms App .NET modern (8, 9, 10) Implicit, dacă profesorul nu cere altceva
Windows Forms App (.NET Framework) .NET Framework 4.x, versiunea veche Dacă laboratorul liceului are un Visual Studio vechi sau așa ați lucrat la clasă

Diferența contează pentru cod copiat de pe internet. Proiectele .NET Framework compilează implicit cu C# 7.3, iar construcții moderne folosite peste tot în exemplele noi nu există acolo. Un using var con = ... dă, pe C# 7.3:

error CS8370: Feature 'using declarations' is not available in C# 7.3.

Alege o dată, la început, și scrie în documentație ce versiune ai folosit.

Ce bază de date legi

Bază de date Cum o legi Pe calculatorul comisiei
SQLite pachetul NuGet Microsoft.Data.Sqlite un fișier lângă aplicație — nimic de instalat
Access (.accdb) OleDbConnection cu Microsoft.ACE.OLEDB cere driverul Access, pe același număr de biți ca aplicația
SQL Server Express / LocalDB SqlConnection cere SQL Server instalat

SQLite e varianta cu cele mai puține surprize la examen și e cea folosită mai jos. Dacă profesorul cere Access, citește capcana cu biții de mai jos înainte să scrii prima linie.

Codul: o clasă pentru bază, evenimentele în formular

Exemplul e un cabinet medical: pacienți, medici, programări. Accesul la date stă într-o clasă separată, nu împrăștiat prin butoane:

// Baza.cs
using Microsoft.Data.Sqlite;

static class Baza
{
    public const string Conexiune = "Data Source=cabinet.db";

    public static SqliteConnection Deschide()
    {
        var con = new SqliteConnection(Conexiune);
        con.Open();
        return con;
    }

    public static void Initializeaza()
    {
        using var con = Deschide();
        using var cmd = con.CreateCommand();
        cmd.CommandText = @"
            CREATE TABLE IF NOT EXISTS pacienti(
                id_pacient INTEGER PRIMARY KEY,
                nume       TEXT NOT NULL,
                telefon    TEXT);
            CREATE TABLE IF NOT EXISTS medici(
                id_medic     INTEGER PRIMARY KEY,
                nume         TEXT NOT NULL,
                specializare TEXT NOT NULL);
            CREATE TABLE IF NOT EXISTS programari(
                id_programare INTEGER PRIMARY KEY,
                id_pacient    INTEGER NOT NULL REFERENCES pacienti(id_pacient),
                id_medic      INTEGER NOT NULL REFERENCES medici(id_medic),
                data_ora      TEXT NOT NULL);";
        cmd.ExecuteNonQuery();
    }
}

Microsoft.Data.Sqlite activează cheile străine implicit: o programare pentru un pacient inexistent e refuzată cu FOREIGN KEY constraint failed, fără nicio setare în plus. Nu toate bibliotecile fac asta — în Python, de exemplu, trebuie activate manual. Dacă folosești altă bibliotecă, verifică rulând PRAGMA foreign_keys;, care trebuie să întoarcă 1.

În formular, butonul și tabelul vizual:

// Form1.cs — în capul fișierului: using System.Data;
private void btnAdauga_Click(object sender, EventArgs e)
{
    if (string.IsNullOrWhiteSpace(txtNume.Text))
    {
        MessageBox.Show("Numele pacientului e obligatoriu.", "Date lipsă");
        return;
    }

    using var con = Baza.Deschide();
    using var cmd = con.CreateCommand();
    cmd.CommandText = "INSERT INTO pacienti(nume, telefon) VALUES (@nume, @telefon)";
    cmd.Parameters.AddWithValue("@nume", txtNume.Text.Trim());
    cmd.Parameters.AddWithValue("@telefon", txtTelefon.Text.Trim());
    cmd.ExecuteNonQuery();

    txtNume.Clear();
    txtTelefon.Clear();
    Reincarca();
}

private void Reincarca()
{
    using var con = Baza.Deschide();
    using var cmd = con.CreateCommand();
    cmd.CommandText = "SELECT id_pacient, nume, telefon FROM pacienti ORDER BY nume";
    using var cititor = cmd.ExecuteReader();
    var tabel = new DataTable();
    tabel.Load(cititor);
    gridPacienti.DataSource = tabel;
}

Ce trebuie să poți explica din codul ăsta:

  • using var închide conexiunea automat la ieșirea din metodă, chiar dacă apare o eroare. O conexiune deschisă și uitată ține fișierul bazei blocat.
  • @nume și Parameters.AddWithValue — valoarea din căsuța de text nu devine niciodată parte din comanda SQL. Vezi secțiunea despre injecție, mai jos.
  • DataTable + DataSource — DataGridView își construiește singur coloanele din rezultatul interogării. Nu adaugi rânduri unul câte unul.
  • Reincarca() după fiecare modificare — ce vezi în tabel e întotdeauna ce e în bază.

Baza.Initializeaza() se apelează o dată, în constructorul formularului, după InitializeComponent(). Aplicația își creează singură baza la prima pornire.

Designerul: două fișiere, unul nu se atinge

Fiecare formular are două fișiere: Form1.cs, unde scrii tu, și Form1.Designer.cs, pe care îl scrie Visual Studio când tragi controale pe fereastră.

  • Nu edita manual Form1.Designer.cs. E regenerat de designer; modificările tale fie dispar, fie strică fereastra.
  • Redenumește controalele înainte să dai dublu-click pe ele. Dublu-click pe button1 creează button1_Click. Peste o lună ai button1_Click, button7_Click și textBox4 și nu mai știi care e care — iar comisia vede asta în cod. btnAdauga, txtNume, gridPacienti se explică singure.
  • Nu șterge metoda unui eveniment direct din cod. Designerul încă are legătura spre ea în Form1.Designer.cs, iar proiectul nu mai compilează — eroarea (de exemplu CS0103: The name 'Form1_Load' does not exist) arată spre un fișier pe care nu l-ai atins. Șterge evenimentul din fereastra Properties → Events, nu din cod.

Interogarea care se notează

SELECT m.nume, m.specializare, COUNT(p.id_programare) AS programari
FROM medici AS m
LEFT JOIN programari AS p ON p.id_medic = m.id_medic
GROUP BY m.id_medic
ORDER BY programari DESC;

LEFT JOIN e alegerea care se justifică: un medic fără nicio programare apare în raport cu 0. Cu JOIN simplu ar dispărea din listă. Diferența asta, spusă în cuvintele tale, e exact motivarea teoretică pe care o cere proba. Rezultatul îl pui într-un DataGridView separat, exact ca la Reincarca(). Tehnicile sunt aceleași ca la interogările SQL de la proba practică.

Datele utilizatorului nu intră niciodată direct în SQL

Pe aceeași bază cu doi pacienți, cu textul ' OR '1'='1 scris în câmpul de căutare:

cmd.CommandText = "SELECT COUNT(*) FROM pacienti WHERE nume = '" + txtCauta.Text + "'";
// -> 2: condiția a devenit adevărată pentru toate rândurile

cmd.CommandText = "SELECT COUNT(*) FROM pacienti WHERE nume = @nume";
cmd.Parameters.AddWithValue("@nume", txtCauta.Text);
// -> 0: textul e căutat ca text, nu executat

Concatenarea cu + transformă textul introdus în cod SQL — SQL injection. Multe tutoriale vechi o folosesc. Dacă ai copiat un astfel de exemplu, schimbă-l înainte de prezentare.

Capcana cu Access: 32 sau 64 de biți

Dacă lucrezi cu o bază .accdb prin OleDbConnection, aplicația și driverul Access trebuie să aibă același număr de biți. Când nu au, conexiunea pică la Open() cu:

The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.

Mesajul pare să spună că driverul lipsește. De cele mai multe ori driverul e acolo, dar pe 64 de biți, iar aplicația rulează pe 32 — sau invers. Se rezolvă din Properties → Build → Platform target, alegând explicit x64 sau x86 ca să se potrivească cu Office-ul instalat. Pe calculatorul comisiei, Office-ul poate fi pe alt număr de biți decât al tău — încă un motiv să testezi acolo din timp, sau să alegi SQLite.

Cum ajunge aplicația pe calculatorul comisiei

Ai două variante de executabil, ambele din Build → Publish sau din linia de comandă:

Variantă Mărime (aplicația de pe pagina asta) Pe calculatorul comisiei
Dependentă de runtime ~2,4 MB, un folder cere .NET Desktop Runtime, aceeași versiune majoră ca proiectul
Self-contained, un singur fișier ~118 MB, un singur .exe pornește pe orice Windows pe 64 de biți, fără nimic instalat
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true

Pentru examen, varianta self-contained e cea sigură: cei 118 MB costă mai puțin decât un calculator pe care lipsește runtime-ul. Baza cabinet.db se creează în folderul din care pornești aplicația; pune-o cu date de test lângă exe și copiază folderul întreg.

Testează pe alt calculator cu cel puțin o săptămână înainte. Adu o copie pe stick, una în cloud, și soluția Visual Studio întreagă, separat.

Planul pe luni

Termenul de depunere e 1 mai, cu referatul profesorului îndrumător. Înapoi de la data aia:

Când Ce faci
Decembrie Alegi tema și șablonul (.NET sau .NET Framework). Entitățile și relațiile pe hârtie
Ianuarie Baza.cs: schema, 20–30 de înregistrări de test pe tabel
Februarie Formularul principal: adăugare, listare în DataGridView, ștergere
Martie Restul formularelor, căutarea, rapoartele cu JOIN și GROUP BY
Aprilie Executabilul testat pe alt PC, documentația, repetiția prezentării
1 mai Depunere

Ce te întreabă comisia

„Ce e un eveniment și unde e legat butonul de funcția lui?” Un eveniment e o acțiune a utilizatorului — click, tastă, încărcarea ferestrei — la care formularul răspunde apelând o metodă. Legătura e în Form1.Designer.cs, scrisă de designer. Arată-le-o.

„Ce face InitializeComponent()?” Construiește controalele desenate în designer: le creează, le poziționează și le leagă evenimentele. De aceea codul tău care folosește controalele vine după el.

„De ce ai pus accesul la date într-o clasă separată?” Ca butoanele să nu știe nimic despre SQL, iar schimbarea bazei de date să se facă într-un singur loc.

„Ce se întâmplă dacă încerc o programare pentru un pacient care nu există?” Baza o refuză, prin cheia străină. Arată-le pe loc.

„De ce LEFT JOIN aici?” Ca medicii fără programări să apară cu zero, nu să dispară din raport.

„Ce ai face altfel dacă ai lua-o de la capăt?” O limitare reală, spusă concret: fără autentificare, căutare doar după nume, un singur utilizator.

Cum decurge proba și ce înseamnă motivarea teoretică: prezentarea proiectului în fața comisiei.

Greșeli frecvente

  • Machetă fără date. Ferestre frumoase care nu salvează nimic.
  • button1, textBox4. Nume implicite pe care nu le mai poți explica.
  • SQL construit cu +. Prima întrebare despre securitate și n-ai răspuns.
  • Conexiuni deschise și neînchise. Fișierul bazei rămâne blocat; folosește using.
  • Cod editat în Form1.Designer.cs. Dispare la următoarea modificare din designer.
  • Metoda unui eveniment ștearsă din cod. Proiectul nu mai compilează.
  • Cod copiat pentru .NET modern într-un proiect .NET Framework. CS8370 la prima compilare.
  • Access pe alt număr de biți. provider is not registered, chiar dacă driverul e instalat.
  • Executabil dependent de runtime, dus pe un calculator fără runtime. Aplicația nu pornește.
  • Bază aproape goală. Trei înregistrări nu produc niciun raport convingător.

Ce livrezi

  1. Aplicația — executabilul, baza cu date de test și soluția Visual Studio cu sursele;
  2. Documentația — schema cu relațiile, capturi ale formularelor, explicația claselor și a interogărilor principale;
  3. Prezentarea — maximum 30 de minute, cu aplicația rulând.

Pentru partea de SQL, teoria e în baze de date și SQL și în interogări SQL, cu probleme rezolvate din examenele reale.

Întrebări frecvente

Se acceptă C# la proiectul de atestat?

Metodologia nu impune un limbaj pentru proiect — tehnologia o stabilește catedra liceului tău. Întreabă profesorul îndrumător înainte să începi și justifică alegerea în documentație.

Visual Studio e gratuit?

Ediția Community e gratuită pentru elevi și pentru proiecte personale. La instalare bifezi componenta pentru dezvoltare desktop .NET.

Windows Forms sau WPF?

Pentru atestat, Windows Forms: designerul e mai simplu și ajungi mai repede la partea care se notează, adică datele. WPF e mai flexibil, dar adaugă XAML, încă un limbaj de explicat.

Ce bază de date să folosesc cu C#?

SQLite, prin Microsoft.Data.Sqlite, dacă nu ți se impune altceva: e un fișier lângă aplicație și nu cere nimic instalat pe calculatorul comisiei. Access merge, dar ai grijă la numărul de biți.

De ce primesc „provider is not registered on the local machine”?

Aplicația și driverul Access au număr diferit de biți. Setează Platform target pe x64 sau x86 în funcție de Office-ul instalat.

De ce codul copiat de pe internet nu compilează?

Cel mai des, pentru că proiectul e .NET Framework, care folosește C# 7.3, iar exemplul e scris pentru .NET modern. Eroarea tipică e CS8370.

Aplicația pornește pe calculatorul meu, dar nu pe al comisiei. De ce?

Probabil ai publicat varianta dependentă de runtime, iar acolo lipsește .NET Desktop Runtime. Publică varianta self-contained, un singur fișier.

Se poate face proiectul în echipă?

Da, în echipă de 2–3 elevi, în funcție de complexitate. Împărțirea naturală: unul pe Baza.cs și rapoarte, altul pe formulare — fiecare trebuie să poată explica și partea celuilalt.

De unde vin informațiile de aici

Cerința ca proiectul să fie un produs software însoțit de prezentarea și motivarea teoretică, termenul de depunere de 1 mai, referatul profesorului îndrumător și posibilitatea lucrului în echipă de 2–3 elevi sunt din Metodologia de organizare și desfășurare a examenului de atestare a competențelor profesionale ale absolvenților claselor de matematică-informatică și matematică-informatică, intensiv informatică, aprobată prin OMECI nr. 4.843/2009 și modificată prin OM nr. 3.009/2021.

Limbajul, baza de date și nivelul tehnic așteptat nu sunt prevăzute în metodologie — se stabilesc de catedra de specialitate a liceului tău. Codul de pe pagina asta a fost compilat și rulat pe .NET 10 cu Microsoft.Data.Sqlite 10.0, iar comportamentele descrise (cheile străine active implicit, injecția prin concatenare, eroarea CS8370 pe C# 7.3, eroarea Access pe un proces cu alt număr de biți, mărimile executabilelor) au fost verificate pe același cod. Verifică întotdeauna cerința profesorului îndrumător.

Cealaltă jumătate

Despre examen

Proiectul e doar una dintre cele două probe. Cum se desfășoară examenul, ce termene are și ce se cere la documentație și la susținere: