Ajutor in C# pentru un necunoscator

Despre PHP, MySQL, HTML, C++, VB, JAVA etc.

Moderator: Moderatori

Post Reply
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Ajutor in C# pentru un necunoscator

Post by CubeKD »

Asa cum scrie in titlu nici macar nu pot sa spun ca sunt incepator in C# dar asta nu m-a impiedicat sa incep un mic program de gestiune.
Mentionez ca utilizez un program Microsoft Visual C# 2008 Express Edition. Pentru inceput am creat o pagina principala plus ferestrele necesare unui program de gestiune, acestea din urma activandu-se cu ajutorul butoanelor din pagina principala.

Ce nu stiu sa fac este cum sa "programez" o fereasta (de exemplu "setari") care odata deschisa aceasta sa anuleze sau mai bine zis sa ascunda meniurile paginii principale fara sa mai am acces la ele decat dupa ce inchid fereastra setari (in cazul de fata).
Mulumesc pentru rabdare si sper ca m-am facut inteles.
Attachments
pagina principala.jpg
setari.jpg
User avatar
whiskey
Posts: 1435
Joined: Tue May 27, 2003 1:30 pm

Re: Ajutor in C# pentru un necunoscator

Post by whiskey »

Nu știu C# dar, dacă am înțeles corect, tu ai nevoie de o fereastră modală (modal dialog). Maybe this helps: http://msdn.microsoft.com/en-us/library ... S.71).aspx
O fereastră modală (spre deosebire de una modeless) permite accesul doar în interiorul ei. Also, vezi că astea modale sunt de două feluri: application modal și document modal. Prima restricționează accesul application wide (ex. nu poți accesa meniul aplicației), iar cea de-a doua îți blochează accesul la widget-urile din documentul curent (ex. un meniu contextual)
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

simplu

whiskey a zis bine, te folosesti de fereastra modala. cum vad eu lucrurile, ai urmatorul pseudocod:


eventul de buton de setari_click(object sender, buttoneventargs e)
{
Form myModalDialog = new Form();
mySettingsMenu.Visible = false; //ascunde meniul
myModalDialog.Show(); //sau .ShowDialog() daca vrei ca la deschiderea formului sa nu mai ai acces in restu' aplicatiei decat in noul form.
}

.. asta iti va deschide fereastra cu setari.

in acea fereastra ai un buton Done (salveaza setari sau ceva de genul)

eventul de buton de btnDone_click(object sender, buttoneventargs e)
{
myModalDialog.Close(); //inchide formu' de setari
mySettingsMenu.Visible = true; //afiseaza meniul
}

sau daca nu vrei sa aglomerezi eventurile de click de buton cu setari de vizibilitate de meniu presupun ca poti sa cauti eventul acelui form OnClose(), sau ceva similar parca se numea, si sa setezi vizibilitatea meniului acolo.

myModalDialog il poti face in aplicatie - add new form

spor

edit: am gresit - mySettingsMenu.Visible = false; //ascunde meniul trebuie inainte sa chemi .ShowDialog()

edit2 - exemplul dat de mine contine Form myModalDialog = new Form(); - asta inseamna ca iti creezi form-ul dinamic, si toate controalele din el la fel, din cod; aici am exemplificat eu gresit, ca nu e simplu daca ma gandesc la asezarea controalelor la modul dinamic in form, o dam in alte balarii, ai nevoie de FlowLayoutPanel etc. Dar daca tu ai creat in design mode un form, si l-ai numit spre exemplu BlablaForm, atunci o sa ai
in loc de: Form myModalDialog = new Form();

Code: Select all

BlablaForm myModalDialog = new BlablaForm();
am explicat tampit, intreaba daca nu intelegi ceva.

work harder
User avatar
whiskey
Posts: 1435
Joined: Tue May 27, 2003 1:30 pm

Re: Ajutor in C# pentru un necunoscator

Post by whiskey »

Eu am înțeles așa:

Code: Select all

appMenu.Visible = false;
settingsForm.ShowDialog(appForm);
appMenu.Visible = true;
Anyway, mie mi se pare cam dubioasă ascunderea meniului, mai ales că nu e accesibil când fereastra modală e deschisă - doar de-aia le-au inventat.
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

Teoretic este corect, ca idee, insa practic nu cred ca merge chiar asa, tu setezi o vizibilitate de control de doua ori pe acelasi event, ceea ce nu cred ca are cum sa mearga; nu spun ca nu ar merge, spun doar ca nu am testat; de obicei eu setez vizibilitatea controalelor in eventuri diferite.

Se pot intampla doua lucruri - sa functioneze, sau: sa se seteze proprietatea aia o data false si apoi true, insa fiindca nu sunt eventuri diferite, setarea sa nu aiba efectul vizual dorit, desi din pdv programatic va merge - proprietatea aia devine false, apoi 2 randuri mai jos devine true.

work harder
User avatar
Bloodred
Posts: 2256
Joined: Thu Feb 28, 2008 10:34 pm

Re: Ajutor in C# pentru un necunoscator

Post by Bloodred »

Codul de după ShowDialog se execută numai când este închisă fereastra respectivă din câte știu eu.
Overhead the albatross hangs motionless upon the air
And deep beneath the rolling waves
In labyrinths of coral caves
The echo of a distant time
Comes willowing across the sand
And everything is green and submarine.

Sistem
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

asa este, pt ca metoda aia intoarce un DialogResult. So?

work harder
User avatar
Bloodred
Posts: 2256
Joined: Thu Feb 28, 2008 10:34 pm

Re: Ajutor in C# pentru un necunoscator

Post by Bloodred »

Păi înseamnă că va funcționa corect și practic, nu doar teoretic, cu setarea Visible false/true pe același event.
Spoiler!
N-am încercat să implementez asta deci s-ar putea să mă înșel, dar nu cred
Intră în metoda de tratare a event-ului, face meniul invizibil, deschide dialogul modal și-n momentul ăsta așteaptă să se închidă acest dialog, nu execută Visible = true. De abia după ce utilizatorul închide dialogul trece la Visible = true, deci face meniul din nou vizibil. Din câte am înțeles eu ăsta-i comportamentul dorit, nu?
Overhead the albatross hangs motionless upon the air
And deep beneath the rolling waves
In labyrinths of coral caves
The echo of a distant time
Comes willowing across the sand
And everything is green and submarine.

Sistem
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

Acum am inteles ce zici; oricum, cazul lui CubeKD este un pic diferit de exemplul lui whiskey. Chiar el a mentionat ca form2 apare pe un click de buton (unul din butoanele din meniu). Asa ca problema este rezolvata din start, are evenimente diferite - o data cand da click pe setari, si alta data cand termina de introdus datele in form-ul ce apare (screenshot-ul sau); deci meniul ala are interval de timp sa se faca invisibil si apoi vizibil.

De curiozitate am facut un mic test si sa vad daca merge si ex lui whiskey, proce

Code: Select all

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label1.Visible = false;
            System.Threading.Thread.Sleep(5000);
            Form2 form = new Form2();
            form.ShowDialog();
            label1.Visible = true;

        }
...nu prea pot sa-l fac sa-mi arate starea initiala a lui form1, de-aia am incercat sa-l adorm cu sleep... adica atunci cand rulez, imi arunca direct child form-ul, fara sa-mi arate main form. poate nu pe constructor trebuie sa chem childu', cine stie poate la eventul de layout din main, ca sa-l conving sa-mi arate starea initiala a sa; oricum sunt mult prea obosit acum sa-mi mai bat capul, vezi poate ai tu vreo idee cum afisezi si main si child mai apoi

later:

ba da, merge, ati avut dreptate amandoi

sunt eu vaca, trebuia sa fiu mai atent

Code: Select all

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Visible = false;
            Form2 form = new Form2();
            form.ShowDialog();
            label1.Visible = true;

        }
deci merge; efectul vizual poate fi vazut tocmai ca stagneaza codului pe ShowDialog(); foarte misto. de fapt nu are de ce sa nu mearga... asta de mai jos e aceeasi chestie.

Code: Select all

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Visible = false;
            System.Threading.Thread.Sleep(5000);
            label1.Visible = true;

        }
in concluzie, ascunderea meniului respectiv nu are rost CubeKD, cred ca voiai sa faci asta nestiind ca ShowDialog() interzice accesul la form-ul din spate; degeaba ascunzi meniul, oricum nu poti da clic pe el

work harder
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Bloodred wrote:Păi înseamnă că va funcționa corect și practic, nu doar teoretic, cu setarea Visible false/true pe același event.
Spoiler!
N-am încercat să implementez asta deci s-ar putea să mă înșel, dar nu cred
Intră în metoda de tratare a event-ului, face meniul invizibil, deschide dialogul modal și-n momentul ăsta așteaptă să se închidă acest dialog, nu execută Visible = true. De abia după ce utilizatorul închide dialogul trece la Visible = true, deci face meniul din nou vizibil. Din câte am înțeles eu ăsta-i comportamentul dorit, nu?
Ai inteles foarte bine ce vreau sa fac, vreau ca meniul principal sa devina inaccesibil atata timp cat este deschisa fereastra initiata din meniul principal iar acesta din urma sa revina la forma initiala dupa ce inchid fereastra initiata din butonul Iesire.

Am tot incercat sugestiile colegilor de pe forum descrise mai sus dar fie imi da erori fie cand dau debugging nu se observa nici o modificare. [smilie=Nice-try.gif]

Sau ar mai fi o idee: fereastra initiata sa se deschida in interiorul meniului principal si ascunzand functiile menuStrip1 din meniul principal pentru a nu avea acces la ele pana nu se inchide fereastra initiata.

Va rog sa-mi iertati lipsa de cunostinte insa acest proiect este o ambitie personala si nu vreau sa ma dau batut. Pana una alta mai "scormonesc" si pe google. [smilie=Respect.gif]
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

posteaza codul, si eroarea.

work harder
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Gata, am reusit. Trebuie sa modific codul urmator:

Code: Select all

private void vizualizareClientiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Vizualizare_clienti Vizualizare_clienti = new Vizualizare_clienti(); Vizualizare_clienti.Show();
        }
cu acesta:

Code: Select all

private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Vizualizare_clienti f = new Vizualizare_clienti();
            f.ShowDialog(this);
        }
Nu mai apare nici o eroare iar singura problema este ca trebuie sa fac aceasta modificare pentru fiecare buton in parte, asta este; daca stiam de la inceput... [smilie=Nice-try.gif]
Nu-i nimic, asa invat. Acum pot sa spun ca am rezolvat o problema dar sigur voi reveni cu noi intrebari. Multumesc pentru ajutor si raman dator cu o :occasion14: pentru fiecare.
User avatar
whiskey
Posts: 1435
Joined: Tue May 27, 2003 1:30 pm

Re: Ajutor in C# pentru un necunoscator

Post by whiskey »

Code: Select all

private void onClick(object sender, EventArgs e)
{
            Form f = new Form();
            f.ShowDialog(this);
}
N-am experiență cu GUI dev (doar ce mă mai joc cu Qt) so am o întrebare: mi se pare mie, sau nu e ok să creezi o instanță nouă a unei ferestre (pentru settings) de fiecare dată când ai nevoie să o afișezi? În fereastra aia ai niște widgets (alte instanțe, iată) care, la un moment dat, îsi pot schimba starea. Plus că mânânci resurse inutil.
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

thats an interesting question, raspunsul m-ar putea ajuta la un proiect curent. te gandesti s-o initializezi in clasa si pe event sa pui doar .Show?

Parerea mea:

Nu are rost sa declari instante de Form mai sus decat un event anume, pentru ca asta inseamna ca va fi global si va fi vazut de toate evenimentele, si implicit va ocupa mai multa memorie tocmai din cauza ca e declarat global.

In plus, nu prea ai nevoie de Form-uri vazute peste tot; asta pentru ca informatia care iti revine din form-ul respectiv, nu o stochezi in proprietatile form-ului in sine, CI IN ALTE OBIECTE. Exemplu:
sa luam exemplul lui CubeKD, el deschide din formul principal formul VizualizareClienti da? Bun, cum as fi facut eu aplicatia asta a lui ar fi fost asa:

Am creat anterior clasa Client cu proprietatile varsta, nume.
Dupa ce creez formul ala VizualizareCLient, fac asa:

Code: Select all

private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Vizualizare_clienti f = new Vizualizare_clienti();
            f.ShowDialog(this);
             Client gigel = new Client(); 
            gigel.varsta = f.textboxAge.Text; // ma rog, cu parse la int etc.
             gigel.nume = f.textboxNume.Text;
            gigel.UpdateClient();
        }
asta e cam pseudocod, ca de fapt un control din form il gasesti nu cu f.textboxAge, ci cu f.Controls["name"] as Control etc. dar se intelege ideea.
deci din cauza asta zic eu ca nu ai nevoie de form-uri globale; informatia din formul ala ai stocat-o deja in obiectul Client, iar de form nu mai ai nevoie, la revedere, .Close(). Nu ma apucam acu sa fac proprietati la formu' in sine, sa am : f.varsta = blabla, f.nume = blabla, n-ar avea sens.

...asta dac-am inteles intrebarea ta cum trebuie. practic am vrut sa raspund la ce-ai mentionat cu starea care trb sa persiste din form in form, etc. formul doar ajuta ca sa populezi obiecte externe.

work harder
User avatar
whiskey
Posts: 1435
Joined: Tue May 27, 2003 1:30 pm

Re: Ajutor in C# pentru un necunoscator

Post by whiskey »

Well, eu așa fac. Iar fereastra secundară și widget-urile din ea sunt inițializate prima oară când afișez fereastra.

LE: vorbeam de ferestre de settings. De asemenea, în exemplul cu clientul (unde nu ai nevoie ca starea să persiste) eu aș fi optat pentru resetarea câmpurilor. De ce să nu refolosești obiectele?
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

Bun, vorbim de ferestre de settings.

Clasa ApplicationSettings in spate, care contine o lista cu numele setarii si valoarea sa. Sau whatever, dupa necesitati.

Code: Select all

        ApplicationSettings settingsCurrent = new ApplicationSettings(); // globala, per aplicatie. ca sa le refolosesti. la asta ma refer.

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Vizualizare_clienti f = new Vizualizare_clienti();
            f.ShowDialog(this);
            settingsCurrent.settingX = value1RetrievedFromForm;
            settingsCurrent.settingB = value2RetrievedFromForm;
           settingsCurrent.UpdateSettings();
        }
LE: vorbeam de ferestre de settings. De asemenea, în exemplul cu clientul (unde nu ai nevoie ca starea să persiste) eu aș fi optat pentru resetarea câmpurilor. De ce să nu refolosești obiectele?
Vorbesti de cazul in care trb sa inserezi mai multe setari, FARA sa inchizi acea fereastra? Daca nu ma insel, cand spui "refolosire de obiecte" te referi la textboxurile alea in care introduci date? Pai ok:

Ai fereastra settings, pe care o deschizi cu

Code: Select all

        private void btnSettings_Click(object sender, EventArgs e)
        {
            Vizualizare_clienti f = new Vizualizare_clienti(); //asta e fereastra, o initializez
            f.ShowDialog(this);//o afisez.
        }
... inseram ce avem nevoie acolo, blabla, bagam date pt setari, etc. apoi avem un buton SUBMIT ca sa trimita datele la server sau in fisier xml sau unde i se mai nazare userului sa pastreze datele vietii

Code: Select all

        private void btnSubmit_Click(object sender, EventArgs e)
        {
                  currentSettings.setareA = whateverValueDinFormuAlaCareEIncaDeschis
                  currentSettings.setareB = whateverValueDinFormuAlaCareEIncaDeschis
                  bool IsSavedOK = currentSettings.Save(); //updatam setarile
                  if (IsSavedOK)
                  {
                            ResetAllFields(); //resetam fieldurile ca sa mai bagam si alte setari sau useri in baza de date sau whatever.
                   }
        }
..eu sunt all pro refolosire
Iar fereastra secundară și widget-urile din ea sunt inițializate prima oară când afișez fereastra.
pai si ce te impiedica sa ai clasa MasterWidget care contine ca proprietati alte Widget objects?

Code: Select all

MasterWidget motherWidget = new MasterWidget();

motherWidget.widgetA = GetWidgetAFromMyNewSettingsWindow();
motherWidget.widgetB = GetWidgetBFromMyNewSettingsWindow();

later edit: ca o chestie utila, MasterWidget se poate implementa cu patternul singleton, sa fi sigur ca nu exista decat un singur MasterWidget care are mai multi widgeti ca proprietati. si te joci cu aia dupa bunul plac. Nush, eu ma folosesc mult de obiecte externe facute de mine, cred ca asta e faza

work harder
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Sunt un pic confuz vizavi de s-a scris un pic mai sus dar fie, poate la un moment dat imi dau seama despre ce este vorba. Acum am o alta problema:
cum trebuie sa procedez ca atunci cand fac clic pe butonul "Calculator" sa imi execute (ca sa zic asa) programul calculator al windows-ului? #-o
Attachments
calc.jpg
calculator.jpg
calculator.jpg (18.98 KiB) Viewed 5180 times
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

System.Diagnostics.Process p= new System.Diagnostics.Process();
p.StartInfo.FileName = "Calc";
p.Start();
p.WaitForExit();

work harder
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Multumesc Andrei, acum ar trebui sa ma orientez spre baza de date. Sa vedem ce iese. [smilie=maniac.gif]
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Am luat pe stick pentru a lucra acasa in continuare la program insa pe calculator imi apare mesajul de jos, despre ce este vorba?
Am gasit o solutie pe tema asta AICI, dar orice as face nu imi dispare acel warning. [smilie=Nice-try.gif]

Problema rezolvata. (inca una) \:D/
Attachments
warning.jpg
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Revin in atentia voastra cu o noua problema. Terminand cu partea grafica a programului de gestiune acum trebuie sa creez baza de date si sa o "combin" ca sa zic asa cu partea grafica. Problema este ca nu stiu cum sa fac baza de date si ce programe sa folosesc, mentionez ca totul trebuie sa fie simplu, nimic complicat.
Dupa ce am rasfoit pe google cateva informatii pe tema asta, am incercat cu Microsoft Access 2003 sa fac ceva, un tabel (nici nu stiu cum sa ii spun) iar apoi l-am conectat la Microsoft Visual C# 2008 Express Edition prin comanda Connect to Database. Cum fac legatura intre campurile din fereastra clienti si si cele din baza de date? :-k

Nu stiu de ce dar am impresia ca nu sunt pe calea cea buna. :sad1:
Un pic de ajutor va rog.
Attachments
clienti.jpg
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Andrei multumesc mult pentru ajutor insa indicatiile din link-ul tau nu ma ajuta pentru ca eu folosesc Windows 7 x64 iar Microsoft Jet 4.0 OLE DB Provider nu se poate folosi pe acest sistem de operare. Cel putin asta am gasit pe net, sau poate m-a inselat engleza mea care nu este prea grozava.

Alta sugestie ai?

P.S. Daca fac o baza de date cu ajutorul Microsoft SQL Server Management Studio este mai usor de conectat la C#? :-k
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

citind aici , realizez ca te afli intr-un cerc vicios in care ai intrat fara voia ta.

Access development + .NET + Win 64bit nu fac casa buna in ultima vreme.
Pt ca proiectul tau sa se poata conecta pe JET 4 oledb provider, va trebui sa setezi proiectul tau sa fie facut pe 32 bit, insa tu folosesti Express Edition care din cate citesc aici nu are optiunea asta. Ai 2 optiuni: faci rost de varianta full a IDEului visual studio sa poti seta proiectul pe x86 CPU in loc de x64, sau te reorientezi spre Sql Server,care e mai de viitor oricum, ca parte pozitita.


sql server e conceput sa fie conectat usor la aplicatiile tale,nu e asta problema. nu-ti dau mura in gura, doar cateva hints

1) daca nu stii SQL - cauta Sql Server tutorials (dupa ce ai instalat in prealabil sql server managementr studio with tools,vezi ca idiotii de la Microsoft au mai multe instaluri, cauta installeru WITH TOOLS (Asa se numeste), ca sa ai si management studio inclus, ca nu mai sta nimeni sa scrie comenzi in consola cand exista IDEu ala). citeste despre ce este un query, un select, un select in select, un update, un create table, etc. familiarizeaza-te putin cu crearea si manipularea de tabele, apoi citeste ce este o procedura stocata, o functie, fa o procedura stoc simpla, o functie simpla,

apoi

2) conectarea la aplicatie: tot ce ai nevoie se afla in namespaceul System.Data.SqlClient - intai creezi o conexiune cu clasa SqlConnection, citeste despre SqlDataReader care iti intoarce rezultate din sql, despre SqlCommand, care reprezinta comanda ce-o trimiti spre sql, mai vezi pe-acolo, si cand mai ai intrebari, posteaza si cod scris de tine care nu merge, sa vedem ce are

work harder
User avatar
CubeKD
Posts: 540
Joined: Thu Apr 29, 2004 12:55 am

Re: Ajutor in C# pentru un necunoscator

Post by CubeKD »

Multumesc mult pentru ajutor, sfaturile tale sunt bine venite si de mare folos. :thumbleft: Am ceva de studiat, stiu ca nu este usor dar cred ca ma voi descurca. Imediat ce mai asimilez ceva cunostinte voi reveni. [smilie=Respect.gif]
dodo
Posts: 116
Joined: Sat Dec 18, 2004 2:48 pm

Re: Ajutor in C# pentru un necunoscator

Post by dodo »

Sustin tot ce a spus andrei in ultimul sau post, dar as propune o a doua varianta, care, dupa parerea mea, s-ar putea sa ti se para mai simpla putin si mai straight-forward : sa folosesti LinqToSql. Dezavantajul acestei metode, in cazul tau, ar fi ca sari peste partea de invatat query-uri sql, conceptul de procedura stocata etc.

1) Cauta documentatie LinqToSql (MSDN, CodeProject, C# Corner ).
2) Am sa iti descriu, pe scurt :

(Later edit: nu am fost atent cand am scris post-ul, tabelul prezentat de tine mai sus se numeste Societati Comerciale. Eu am folosit in cadrul postului Clients)

Linq face mapare intre obiectele date (data types) si tabele din baza de date.
(Observatie: in printscreen-ul de mai sus, am vazut ca nu ai un camp Id, care, in mod uzual, este utilizat pentru a identifica in mod unic un record (cheie primara). In cazul tabelei Clienti, ai putea folosi CUI-ul ca si id, ca primary key, desi recomand sa mai pui un camp IdClient, pe care sa il setezi de tip identity => db-ul va genera in id unic, incepand de la 0, pe care il va incrementa cu fiecare record adaugat; astfel, nu trebuie sa iti ma bati capul cu generarea unui id nou de fiecare data cand vrei sa inserezi ceva.)

Pas 1: creezi tabelele, definesti cheia primara.
ex : tabelul Clients de mai sus

Pas 2: in cod, ai clasa Clients.cs, care modeleaza conceptul de Client.
Pentru a face maparile, clasa ta va arata asemanator:

Code: Select all

[Table(Name="dbo.Clients")]
public class Client
{
     // IsPrimaryKey e evident ce face; IsDbGenerated ii spune framework-ului ca aceasta proprietate, IdClient, se va mapa pe un record camp declarat Identity in DB.
     [Column(IsPrimaryKey = true, IsDbGenerated = true)] 
     public int IdClient { get; set; }
     
     [Column]
     public string Societate { get; set; }

     [Column]
     public string CUI { get; set; }

     // alte proprietati ale clasei
}
Pas 3: Creezi un DataContext pentru fiecare mapare Clasa-Tabel_DB. DataContext-ul reprezinta un wrapper, cu ajutorul caruia efectuezi diverse operatii cu baza de date. Documenteaza-te putin pe net.

Code: Select all

public class ClientsDataContext : DataContext
{
     public ClientsDataContext(string connectionString) : base(connectionString) { }    
}
Pas 4: Clasa din layer-ul DataAccess, care opereaza asupra bazei de date:
In aceasta clasa, sunt declarate atat DataContext-ul, cat si un obiect de tipul Table, care este un "holder" pentru datele tale => poti implementa astfel un fel de mecanism de cache, sa nu faci n call-uri la baza de date (not healthy).

Code: Select all

public class ClientsDAL
{
     private ClientsDataContext _clientsDataContext = null;
     private Table<Client> _clientsTable = null;

     private ClientsDataContext ClientsContext
     {
          if(_clientsDataContext == null)
               _clientsDataContext = new ClientsDataContext(connectionString);

          return _clientsDataContext;
     }
     private Table<Client> ClientsTable
     {
          if(_clientsTable == null)
              _clientsTable = ClientsContext.GetTable<Client>();

          return _clientsTable;
     }

     //metode de tipul get:
     public Client GetClient(int idClient)
     {
          IQueryable<Client> query = ClientsTable.Where<Client>(client => client.IdClient == idClient);
          if(query.Count() > 0)
               return query.First<Client>();

          return null;
     }

     public Client GetClient(string cui)
     {
          IQueryable<Client> query = ClientsTable.Where<Client>(client => client.CUI.ToLower() == cui.ToLower());
          if(query.Count() > 0)
               return query.First<Client>();

          return null;
     }
  
     public List<Client> GetClients()
     {
          if(ClientsTable.ToList<Client>().Count > 0)
               return ClientsTable.ToList<Client>();

          return null;
     }

     //metode de insert
     public Boolean SaveClient(Client client)
     {
           if(client != null)
           {
                 ClientsTable.InsertOnSubmit(client);
                 try
                 {
                       ClientsContext.SubmitChanges();
                       return true;
                 }
                 catch(Exception ex)
                 {
                       return false;
                 }
           }
     }

     //update
     public Boolean UpdateClient(Client client)
     {
              //trebuie sa cauti, dupa id, clientul care e in baza de date, sa il actualizezi
          var query = from c in ClientsTable
                                     where c.IdClient == client.IdClient
                                     select c;
          if(query.Count() == 0)
               return false; // daca ajungi aici, inseamna ca nu s-a gasit clientul cu id-ul dat ca param. sau te intorci cu false si afisezi un mesaj sau apelezi metoda de insert => return this.SaveClient(client);
          
          Client oldClient = query.First<Client>();

          oldClient.CUI = client.CUI;
          oldClient.Societate = client.Societate;
          // .....

          try
          {
                ClientsContext.SubmitChanges();
                return true;
          }
          catch(Exception ex)
          {
                return false;
          }
     }
}
In metoda de Insert, obiectul Client va fi adaugat doar in Table (care e un obiect al .net-ului), nu direct in DB. Pentru a face commit-ul in DB, se apeleaza metoda SubmitChanges() din DataContext (blocul try-catch). Pentru a evita si mai mult acele call-uri la baza de date, de care spunea mai sus, ai putea scoate acel bloc try-catch din metodele de insert, delete pe care le vei avea, si sa il pui intr-o metoda, pe care sa o denumesti ceva de genul SubmitChangesToDb, CommitToDb, pe care sa o apelezi o singura data, dupa ce ai terminat de adaugat toti clientii. Doar atunci, continului ClientsTable se va sincroniza cu tabelul Clients din baza de date.

In cazul metodelor de update, oldClient nu este o copie a record-ului din ClientsTable, ci chiar o referinta spre record-ul respectiv. Deci orice modificare asupra proprietatilor Client-ului, se vor face direct in Table. La SubmitChanges() acestea vor fi introduse in DB.


Am incercat sa expun in code snippet-urile de mai sus modul de a folosi Linq pentru operatiile de I/O cu Db-ul. Sper ca am fost destul de clar, si te vei prinde repede. Nu e greu, dupa ce ai putin exercitiu, o sa zboare chestiile astea.



Acum, in UI vad ca ai folosit binding navigator-ul. Nu am mai folosit WindowsForms de ceva vreme, dar din cat mai tin minte, acel navigator ofera o proprietate DataSource. Ei bine, la acel DataSource, poti trimite o lista de clienti. Fiecare camp din acel navigator ar trebui sa aiba ceva de genul Target, in sectiunea Proprieties a UI-ului IDE-ului (disclaimer: nu mai tin minte cum se face, nu am folosit demult) In acest caz, setezi fiecarui camp la target proprietatea obiectului Client care doresti sa fie afisata.

ceva in genul, presupunand ca ai o instanta a ClientDAL-ului :

Code: Select all

List<Client> clients = clientDAL.GetClients();
if(clients != null)
{
     bindingNavigatorClients.DataSource = clients;
     bindingNavigatorClients.BindData();
}
Sper ca am reusit sa te ajut, sa iti ofer o alternativa la ceea ce ti-a sugerat andrei. Alegerea este a ta.
Avantajele metodei lui andrei : vei invata SQL, query-uri, proceduri stocate, constangeri etc;
Avantajele metodei sugerate de mine : mai rapida ( atat ca timp de development, cat si ca timp de executie <aici s-ar putea sa fie ceva discutii, cum ca procedurile stocare ar fi mai rapide, sau metoda in general ar fi mai rapida; depinde de multi factori, pentru ceea ce ai nevoie de tu, e foarte ok), mai simpla dupa ce te prinzi de procedeu, mai clara.


Disclaimer 1 : Acesta este primul meu post in sectiunea de programare, in care ofer un sfat / exemplu / sugestie. Asadar, sunt deschid la critici.
Disclaimer 2 : Post-ul presupune ca ai concepte de OOP; am presupus ca ai si conceptul de arhitectura n-tier a unei aplicatii (UI, BusinessLayer, DataAccessLayer, DataTypesLayer);
Disclaimer 3 : Varianta prezentata mai sus este doar un schelet, pentru exemplificare; nu e varianta cea mai optima de scriere a unui cod.
Disclaimer 4 : In viitoarele editari ale postului :)
Last edited by dodo on Thu Jan 13, 2011 2:39 pm, edited 1 time in total.
User avatar
andrei
Posts: 7528
Joined: Sun Mar 24, 2002 2:00 am

Re: Ajutor in C# pentru un necunoscator

Post by andrei »

ca o completare la ce s-a scris mai sus, daca nu intelegi linia

Code: Select all

List<Client> clients = clientDAL.GetClients();
..aia se numeste lista generica (e un array mai avansat un pic, si mai usor de folosit), si poti invata despre liste generice aici.

Unde vezi

Code: Select all

Blabla<>
<> ala defineste o clasa generica, si intre semnele < > intra orice tip de obiect. e foarte folositor in momentul in care vrei sa citesti toate valorile dintr-o lista, sa cauti una anume printre ele.

work harder
Post Reply