offline
- Fil
![Male](https://www.mycity.rs/templates/simplified/images2/user-sex.gif)
- Legendarni građanin
- Pridružio: 11 Jun 2009
- Poruke: 16586
|
- 18Ovo se svidja korisnicima: ilovephp, vasa.93, CyberSrbin032, Srki_82, ivance95, NIx Car, dejanod, TheDelliRus, mcrule, Jimmy4, TwinHeadedEagle, nike992, thebrainstorm, E.L.I.T.E., DzoniB, Rorschach, 90.42, ndukan
Registruj se da bi pohvalio/la poruku!
[0] Uvod
* Za 9000. poruku, tradicionalno --> poklon čitaocima novi članak
Do sada je u članku forsirano okruženje MonoDevelop, na operativnom sistemu Linux. U ovome članku će biti obrađen rad sa razvojnim okruženjem Visual Studio, na operativnom sistemu Windows.
Preuzmite: Visual Studio 2012 Express for Windows Desktop
* express verzija je besplatna i radiće bez regsitracije 30 dana; registracijom, dobijamo besplatan ključ (serijski broj) za softver.
Takođe, u članku će biti rađeno sa Microsoft Access 2007 bazom podataka (ekstenzija: accdb)
Ideja članka je da čitaoca motiviše da istražuje i da, koristeći uputstva za ovaj članak i prethodne članke, unapredi kod, doradi ga i pokuša da napravi sopstvenu bazu podataka.
Ponegde u članku će biti napisan "nagoveštaj" (hint), šta se može pokušati, a ako članak bude popularan, članak će biti proširen i sa drugim konceptima (npr. kreiranje niti koje brišu unose iz baze, po nekom kriterijumu i drugo).
Zadatak je sledeći: treba napraviti Windows aplikaciju koja će u bazu podataka unositi određene podatke, vezane za nekog forumaša na MyCity-ju. Ti podaci neka budu: broj forumaša, njegovo ime, prezime, nadimak (nick) i informacija da li je korisnik vidljiv ili sakriven na forumu.
Za korisnike u bazi treba omogućiti tabelarni prikaz korisnika i preko liste implementirati navigaciju za unose u bazi: prikaz prvog i poslednjeg korisnika u bazi, kao i prethodnog i sledećeg korisnika u bazi.
* Napomena: postoje različiti pristupi komuniciranja sa bazom podataka, i lakši i teži od ovde opisanog (recimo kroz kontrole na formi, zatim upotrebe drugih klasa i sl.). Ovo je samo jedna od različitih mogućnosti.
[1] Kreiranje projekta i dizajn forme
- Pokrenimo alat Visual Studio i kreirajmo novi projekat: File --> New Project....
- Odaberite opcije sa sledeće slike i kliknite na dugme OK:
Slika 1: Kreiranje Windows Forms aplikacija
Dočekaće vas prazna forma. Odabrao sam da najpre uradimo dizajn forme, jer dizajn nije mnogo bio u fokusu u prethodnim člancima, a i ja kada pročitam neki zahtev, pokušavam da zamislim u glavi kako bi mogla da izgleda forma te aplikacije. Dakle, od značaja nam je panel Toolbox (pregledajte listu panela u meniju View. Ako slučajno isključite neki toolbar ili panel, ovaj meni je mesto gde ga možete opet aktivirati). Proučite malo ovaj panel i vidite kakvih sve komponenti ima u njemu.
Slika 2: prikaz najčešćih kontrola u panelu Toolbox
Kontrole (komponente) se dodaju na formu dvostrukim klikom ili prevlačenjem kontrole na formu. Takođe, ako je potrebno više identičnih kontrola na formi, one se mogu brzo kopirati (CTRL + C, CTRL + V).
Ja sam zamislio da forma izgleda ovako:
Slika 3: prikaz jedne od mogućih solucija za dizajn forme
Dakle, dodajmo kontrole na formu i podesimo njihove osobine (eng. properties):
Slika 4: prikaz promene osobina labele na formi
Kroz panel Properties menjamo osobine kontrola, na primer: ime kontrola, tekst koji kontrola ispisuje, vidljivost kontrole i druge. Za stanje kao na slici 3, trebaće nam sledeće kontrole:
- 5 labela (Label)
- 4 polja za unos teksta (TextBox)
- 1 padajuća lista (ComboBox)
- 1 kontrola koja može imati tabelarni prikaz (DataGridView)
- 6 dugmadi (Button)
Rasporedite kontrole i izmenite im osobine tako da odgovaraju stanju na slici 3; ja sam ovako podesio osobine kontrola na formi:
+ Labele:Labela Broj:
- Name: lblBroj
- Text: Broj
Labela Ime:
- Name: lblIme
- Text: Ime
Labela Prezime:
- Name: lblPrezime
- Text: Prezime
Labela Nick:
- Name: lblNick
- Text: Nick
Labela Vidljivost:
- Name: lblVidljivost
- Text: Vidljivost
+ Polja za unos teksta:- Name: txtBroj
- Name: txtIme
- Name: txtPrezime
- Name: txtNick
+ Padajuća lista:- Name: cbxVidljivost
- Items: [kliknuti na "..."] i uneti sledeće stavke, jednu ispod druge, kao na slici:
+ Grid:- Name: dgvGrid
- ColumnHeadersVisible: false
- RowsHeadersVisible: false
- ReadOnly: true
eksperimentišite sa ovim osobinama, naučite šta one znače "kroz igru". Recimo, podesite Anchor, koji je podrazumevano: top, left, da bude: top, left, right. Kada pokrenete aplikaciju, menjajte desnu stranu forme i pogedajte šta se dešava sa gridom.)
+ DugmadName: btnUnesi
Text: Unesi
Name: btnPrikazi
Text: Prikaži
Name: btnPrvi
Text: <<
Name: btnPrethodni
Text: <
Name: btnSledeci
Text: >
Name: btnZadnji
Text: >>
[2] Dodavanje novih klasa i definisanje klase Forumas
- Dodaćemo novu klasu u projekat: unutar panela Solution Explorer, kliknite desnim tasterom miša na ime projekta, birajte stavku Add i odaberite stavku Class.... Dajte joj ime "Forumas".
Slika 5: dodavanje nove klase u projekat
Slika 6: odabir i imenovanje klase
Kada "uđemo" u klasu, primetićemo da su već definisane neke "using" linije, namespace i definicija klase Forumas.
U ovoj klasi ćemo definisati privatna polja i odgovarajuće Property polja ("setere" i "getere"), preko kojih se može čitati i/ili pisati u neko polje (tj. promenljivu).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Forumasi
{
class Forumas
{
private int brojForumasa;
public int BrojForumasa
{
get { return brojForumasa; }
set { brojForumasa = value; }
}
private string ime;
public string Ime
{
get { return ime; }
set { ime = value; }
}
private string prezime;
public string Prezime
{
get { return prezime; }
set { prezime = value; }
}
private string nick;
public string Nick
{
get { return nick; }
set { nick = value; }
}
private string vidljivost;
public string Vidljivost
{
get { return vidljivost; }
set { vidljivost = value; }
}
public Forumas()
{
//parametherless konstruktor
}
public Forumas(int brFor, string ime, string prez, string nick, string vidljivost)
{
brojForumasa = brFor;
this.ime = ime;
prezime = prez;
this.nick = nick;
this.vidljivost = vidljivost;
}
}
}
Lak način da kreirate polja i njegove settere i gettere je da ukucate propfull i dva puta pritisnete taster TAB. Rezultat ove akcije je sledeće parče koda koje se generiše automatski (code snippet):
private int myVar;
public int MyProperty
{
get { return myVar;}
set { myVar = value;}
}
Na ovaj način ćete brzo da "završite" klasu i njene konstruktore.
Napomena: ukoliko se desi da se podudari ime polja klase sa imenom parametra u konstruktoru, mora se koristiti ključna reč this. Vidite kod. Ključna reč this ukazuje na to da se radi o elementu klase, a ne konstruktora. Dakle: this.ime=ime; označava da se polju klase s nazivom ime, dodeljuje vrednost parametra ime iz konstruktora.
[3] Kreiranje baze podataka
OK, pošto je prošao šablonski deo, da se opet vratimo na zanimljive stvari.
- Pokrenite Access i kreirajte New Blank Database.
- Desnim tasterom miša kliknite na "Table1" i odaberite Design View. Kada se otvori polje za unos imena, unesite: "TForumas".
- Unesite podatke kao na sledećoj slici:
Slika 7: kreiranje strukture tabele u Design View-u
Polja su, dakle: "BrojForumasa", "ImeForumasa", "PrezimeForumasa", "NickForumasa", "VidljivostForumasa".
BrojForumasa treba definisati kao primarni ključ (videti opciju sa ribbona: Primary Key)
Primarni ključ jednoznačno identifikuje zapis u bazi. Broj forumaša, dakle, jednoznačno identifikuje nekog forumaša i ne može se desiti da postoje dva člana foruma koji se vode pod istim brojem.
Ja sam sačuvao bazu unutar: C:\
Ovi unosi iz Design View-a će se transponovati u kolone unutar Datasheet View-a.
Inače, eksperimentište sa osobinama ovih unosa. Na primer, dozvoljena veličina stringa, ili kod primarnog ključa uočite da je definisano da nema duplikata.
Izgled baze kada sam završio aplikaciju i preko nje uneo par forumaša:
Slika 8: Pregled unosa tabele u Datasheet View-u
[4] Kreiranje klase Broker
Klasa Broker je usko vezana za bazu podataka; u njoj će se manipulisati konekcijama, transakcijama, zadavaće se SQL upiti i drugo.
Najpre, kreirajmo klasu Broker (videti sliku 5 i sliku 6).
U tekstu će biti objašnjeni delovi koda, a na kraju objašnjenja će, unutar spoilera, biti dodat čitav kod.
- Najpre, neophodno je dodati par using direktiva, prvenstveno:
Citat:using System.Data;
using System.Data.OleDb;
- Dalje, deklarisaće se sledeće promenljive: komanda, konekcija i transakcija i definisati konekcioni string:
OleDbCommand command;
OleDbConnection connection;
OleDbTransaction transaction;
private string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Forumasi.accdb; Persist Security Info=False;";
Uočimo specifičnu sintaksu konekcionog stringa. Izgled konekcionog stringa zavisi od više faktora, na primer tip baze (Access, SQL Server, MySQL...) i drugih parametara (zaštita i drugo).
Primer konekcionog stringa koji sam koristio u Visual Studio 2005 za staru Access-ovu bazu (format 2000, ekstenzija mdb):
private string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\NekaBaza.mdb;";
Koristan link za konekcione stringove: ConnectionStrings
* odaberite sa kojom bazom radite i vidite primere konekcionih stringova
* Još jedan primer, sa foruma MyCity: LINK
- Unutar konstruktora klase broker izvršimo inicijalizaciju konekcije, na osnovu konekcionog stringa:
public Broker()
{
connection = new OleDbConnection(connectionString);
}
- Transakcija se može shvatiti kao logičko izvršenje jedne jedinice posla. Transakciju započinjemo kada treba da uradimo neke aktivnosti nad bazom i to kada je otvorena konekcija na bazu:
public void PocniTransakciju()
{
try
{
if (connection.State != ConnectionState.Open)
connection.Open();
transaction = connection.BeginTransaction();
}
catch (Exception ex) { MessageBox.Show("Doslo je do greske prilikom pocinjanja transakcije" + ex); }
}
Transakcije se odvijaju po principu "sve ili ništa", i postoje izvesne osobine transakcije (ACID). Saznajte više o transakcijama: LINK.
- Sledeći kod će ubaciti objekat klase Forumas u bazu:
public void InsertForumas(Forumas fr)
{
PocniTransakciju();
command = new OleDbCommand();
string upit = "INSERT INTO TForumas VALUES('" + fr.BrojForumasa + "','" + fr.Ime + "','" + fr.Prezime + "','" + fr.Nick + "','" + fr.Vidljivost + "')";
try
{
command.CommandText = upit;
command.Connection = connection;
command.Transaction = transaction;
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw new Exception("Broker.InsertForumas", ex);
}
finally { connection.Close(); }
}
Dakle, nakon što započnemo transakciju, zadaje se SQL komanda koju treba izvršiti nad bazom. Za potrebe ovog primera, neophodno je znati osnove SQL jezika (vidi LINK). Određenoj komandi, dakle, dodeljujemo konkretan upit, konekciju i transakciju, nakon čega je izvršavamo.
Dobra praksa je koristiti try-catch-finally blokove baš po ovoj šemi:
- unutar try bloka definišemo gde ima "prostora za grešku", uključujući i Commit transakcije. Ako dođe do greške, unutar catch bloka poništavamo transakciju sa rollback, dok u finally bloku (koji se svakako izvršava) zatvaramo konekciju. Izuzeci su objašnjeni u jednom od prethodni članaka, pa ako ovaj deo nije jasan, preporučujem da se taj članak pročita.
- Select SQL upit koji vadi sve zapise iz baze je obrađen u sledećem kodu:
public DataTable SelectForumas()
{
PocniTransakciju();
command = new OleDbCommand();
try
{
command.CommandText = "SELECT * FROM TForumas";
command.Connection = connection;
command.Transaction = transaction;
DataTable forumasi = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter(command);
adapter.Fill(forumasi);
transaction.Commit();
return forumasi;
}
catch (Exception ex)
{
transaction.Rollback();
throw new Exception("Broker.SelectForumas", ex);
}
finally { connection.Close(); }
}
}
}
Kao što se vidi, i ovaj upit je jednostavan. Inače, ovi upiti su osnovni i jednostavni.
Za domaći, probajte da napišete DELETE upit. U kasnijem proširenju članka će i on biti objašnjen.
Elem, ovde umnogome olakšava posao objekat klase DataAdapter, koji je sposoban da na osnovu prosleđenog upita popuni DataTable (koji je i izlaz iz funkcije).
+ Vidi kompletan kodusing System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;
using System.Windows.Forms;
namespace Forumasi
{
class Broker
{
OleDbCommand command;
OleDbConnection connection;
OleDbTransaction transaction;
private string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Forumasi.accdb; Persist Security Info=False;";
public Broker()
{
connection = new OleDbConnection(connectionString);
}
public void PocniTransakciju()
{
try
{
if (connection.State != ConnectionState.Open)
connection.Open();
transaction = connection.BeginTransaction();
}
catch (Exception ex) { MessageBox.Show("Doslo je do greske prilikom pocinjanja transakcije" + ex); }
}
public void InsertForumas(Forumas fr)
{
PocniTransakciju();
command = new OleDbCommand();
string upit = "INSERT INTO TForumas VALUES('" + fr.BrojForumasa + "','" + fr.Ime + "','" + fr.Prezime + "','" + fr.Nick + "','" + fr.Vidljivost + "')";
try
{
command.CommandText = upit;
command.Connection = connection;
command.Transaction = transaction;
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw new Exception("Broker.InsertForumas", ex);
}
finally { connection.Close(); }
}
public DataTable SelectForumas()
{
PocniTransakciju();
command = new OleDbCommand();
try
{
command.CommandText = "SELECT * FROM TForumas";
command.Connection = connection;
command.Transaction = transaction;
DataTable forumasi = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter(command);
adapter.Fill(forumasi);
transaction.Commit();
return forumasi;
}
catch (Exception ex)
{
transaction.Rollback();
throw new Exception("Broker.SelectForumas", ex);
}
finally { connection.Close(); }
}
}
}
[5] Upotreba generičkih listi i obrada događaja dugmadi
Za početak, otvorite formu koju ste dizajnirali i dvostrukim klikom overite svu dugmad na formi. Dvostrukim klikom na neko dugme ćemo automatski formirati deo koda koji obrađuje događaj "On Click".
Na primer, dvostrukim klikom na dugme "Prikazi", kreiraće se ovaj deo koda:
private void btnPrikazi_Click(object sender, EventArgs e)
{
// neki_blok_koda
}
Dakle, svaki put kada kliknemo na dugme "Prikazi", izvršiće se neki_blok_koda (deo koda koji definišemo).
Vratimo se na početak klase naše forme (ja joj promenih ime u MyCity) i unesimo ispod definicije klase sledeće:
Broker broker = null;
List<Forumas> lista = null;
int tekuciIndex = 0;
List<Forumas> je generička lista, dakle, lista koja se sastoji od specifičnih objekata (forumasa). Za upotrebu generičkih listi, neophodna je using direktiva: using System.Collections.Generic;
tekuciIndex će nam služiti kao pokazivač na neki element u generičkoj listi.
Unutar konstruktora forme se dodeljuju vrednosti brokeru, listi i vrši se inicijalizacija komponenti forme.
Zbog preglednosti koda, mogu se koristiti tzv. regioni. U kodu se može videti da sam definisao dva regiona:
Slika 9: Upotreba regiona radi preglednosti koda
Klikom na plusić, "razvija se" deo koda vezan za definisani region. Region se formira na sledeći način:
Citat:#region Ime regiona
#endregion
Prvi region je vezan za listu: + VIDI KOD#region Manipulacija s listom
public void TransformisiUListu(DataTable datatable)
{
lista.Clear();
foreach (DataRow red in datatable.Rows)
{
Forumas fr = new Forumas((int)red[0], (string)red[1], (string)red[2], (string)red[3], (string)red[4]);
lista.Add(fr);
}
}
public void PrikaziForumasaNaPoziciji(int index)
{
txtBroj.Text = Convert.ToString(lista[index].BrojForumasa);
txtIme.Text = lista[index].Ime;
txtPrezime.Text = lista[index].Prezime;
txtNick.Text = lista[index].Nick;
cbxVidljivost.SelectedItem = lista[index].Vidljivost;
}
public bool PostojiForumasUListi(int brFor)
{
foreach (Forumas fr in lista)
{
if (fr.BrojForumasa == brFor)
return true;
}
return false;
}
#endregion
Metoda TransformisiUListu uzima objekat tipa DataTable i transformiše u listu forumaša. Ovde nema mnogo mudrosti: treba izvrtiti petlju tako da se na osnovu svakog reda izvuku podaci i napravi forumaš - koga ćemo ubaciti u listu u svakoj iteraciji.
Metoda PrikaziForumasaNaPoziciji je zadužena da na osnovu zadatog indeksa, zaviri na tu poziciju u generičkoj listi i da, na osnovu konkretnog forumaša u listi - popuni Text Boxove i Combo Box na formi.
Metoda PostojiForumasUListi je zamišljena da se koristi u svrhu zaštitnog mehanizma, dakle, da nije moguće uneti dva forumaša koji bi imali isti brojForumasa.
Ovaj mehanizam se zasniva na proveri iz liste! Petlja izvrti da li je broj nađen u listi --> za domaći: osmisliti metodu koja će čitati vrednosti iz baze kako bi videla da li ima te vrednosti u bazi (može biti objašnjeno u ekstenziji članka).
Drugi region je vezan za dugmad.
btnUnesi_Click - treba da proveri (na neki način, a ovde čitamo iz liste) da li već ima forumaša sa konkretnim brojem i ako nema, napravi objekat forumaša na osnovu podataka iz forme, i najzad, da "kaže" brokeru da ga ubaci u bazu.
btnPrikazi_Click - služi za punjenje grida, njegovo osvežavanje (da se prikažu ažurni podaci), i transformaciju ovih podataka u listu.
Ostali dugmići su navigacioni i barataju sa indeksom i prikazuju određenog forumaša u zavisnosti od pozicije u listi (određene na osnovu tog indeksa).
+ Vidi kompletan kod klaseusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Forumasi
{
public partial class MyCity : Form
{
//inicijalizacija na nivou klase
Broker broker = null;
List<Forumas> lista = null;
int tekuciIndex = 0;
public MyCity()
{
InitializeComponent();
//dodela vrednosti unutar konstruktora
broker = new Broker();
lista = new List<Forumas>();
}
#region Manipulacija s listom
public void TransformisiUListu(DataTable datatable)
{
lista.Clear();
foreach (DataRow red in datatable.Rows)
{
Forumas fr = new Forumas((int)red[0], (string)red[1], (string)red[2], (string)red[3], (string)red[4]);
lista.Add(fr);
}
}
public void PrikaziForumasaNaPoziciji(int index)
{
txtBroj.Text = Convert.ToString(lista[index].BrojForumasa);
txtIme.Text = lista[index].Ime;
txtPrezime.Text = lista[index].Prezime;
txtNick.Text = lista[index].Nick;
cbxVidljivost.SelectedItem = lista[index].Vidljivost;
}
public bool PostojiForumasUListi(int brFor)
{
foreach (Forumas fr in lista)
{
if (fr.BrojForumasa == brFor)
return true;
}
return false;
}
#endregion
#region Obrada dogadjaja dugmadi
private void btnUnesi_Click(object sender, EventArgs e)
{
if (!PostojiForumasUListi(Convert.ToInt32(txtBroj.Text)) & txtBroj.TextLength > 0)
{
Forumas forumas = new Forumas(Convert.ToInt32(txtBroj.Text), txtIme.Text, txtPrezime.Text, txtNick.Text, cbxVidljivost.SelectedItem.ToString());
broker.InsertForumas(forumas);
}
else MessageBox.Show("U bazi vec postoji forumas sa zadatim brojem!!!");
}
private void btnPrikazi_Click(object sender, EventArgs e)
{
dgvGrid.DataSource = broker.SelectForumas();
dgvGrid.Refresh();
TransformisiUListu(dgvGrid.DataSource as DataTable);
}
private void btnPrvi_Click(object sender, EventArgs e)
{
tekuciIndex = 0;
PrikaziForumasaNaPoziciji(tekuciIndex);
}
private void btnPrethodni_Click(object sender, EventArgs e)
{
if (tekuciIndex > 0)
{
tekuciIndex--;
PrikaziForumasaNaPoziciji(tekuciIndex);
}
}
private void btnSledeci_Click(object sender, EventArgs e)
{
if (tekuciIndex < lista.Count - 1)
{
tekuciIndex++;
PrikaziForumasaNaPoziciji(tekuciIndex);
}
}
private void btnZadnji_Click(object sender, EventArgs e)
{
tekuciIndex = lista.Count - 1;
PrikaziForumasaNaPoziciji(tekuciIndex);
}
#endregion
}
}
Do sledećeg članka
E, da I kome zatreba ( ) , evo ga gotov solution sa bazom
[url=https://www.mycity.rs/must-login.png
|