HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Adatkapcsolat tetszőleges kontrolokhoz, szinkronizálással


Példaprogram letöltése

6727 bájt

Ha az adatbázisaink tábláiból nem csak lekérdezni szeretnénk adatokat, hanem azokat fel is kellene tölteni és ehhez felhasználói beavatkozás is szükséges, akkor biztosítanunk kell, hogy különféle kontrolokhoz (DataGrid, TextBox, DateTimePicker, stb.) hozzá kell kötnünk az adattáblánk megfelelő oszlopait, hogy ezeken keresztül a felhasználó megadhassa a szükséges adatokat. Biztosítanunk kell az adatok szinkronizációját is. Vagyis, ha egy DataGrid-ben egy másik sorra lép a felhasználó, akkor célszerű, ha a többi adatmegjelenítő kontrol is ennek a sornak az adatait mutatja. További megoldandó feladat az is, hogy biztosítsuk az adatok egyedi formázását úgy, hogy azok továbbra is szerkeszthetők maradjanak. E cikkben e feladatok megvalósításának járunk utána.

Az adatok kontrolokhoz való kötését elsősorban a Binding osztály valósítja meg. Mielőtt megismerkednénk ezzel az osztállyal, hozzunk létre egy adathalmazt, melyet felhasználhatunk.
Ehhez egy DataTable osztályt készítünk, melyben létrehozunk egy olyan táblát, mely két oszlopot tartalmaz. Az egyikben egy dátum típus, míg a másikban egy Int32 típus kap helyet.
    Dim dt As New DataTable("Table01")
    dt.Columns.Add("Date", GetType(DateTime))
    dt.Columns.Add("Value", GetType(Int32))
Következzen az adat sorok létrehozása, melyhez egy új DataRow osztály példányát hozzuk létre a DataTable NewRow függvényét meghívva. Egy ciklus segítségével több adatsort is generálunk a példánkhoz.
    Dim dr As DataRow
    Dim r As New Random()
    Dim i As Integer
    For i = 0 To 99
      dr = dt.NewRow()
      dr(0) = DateTime.Now.AddDays(i)
      dr(1) = r.Next(Int32.MaxValue)
      dt.Rows.Add(dr)
    Next i
Végül az így elkészített adattáblát egy DataSet osztályban tároljuk.
    ds = New DataSet()
    ds.Tables.Add(dt)
Nézzük, most miként köthetjük különféle kontrolokhoz a létrehozott adatokat. Minden olyan osztály rendelkezik DataBindings property-vel, ami ControlBindingsCollection osztály típusú, mely a Control osztályból származik. A DataBindings property-n keresztül tehát elérhetünk egy olyan kollekciót, mely tartalmazza a már létrehozott adatkapcsolatokat, illetve segít bennünket új kapcsolat létrehozásában is. Ez utóbbihoz az Add függvény nyújt segítséget, melynek két változata is van:
Add
Osztály: System.Windows.Forms.ControlBindingsCollection
public Binding Add(
string propertyName, object dataSource, string dataMember
);
Új adatkapcsolat létrehozását valósíthatjuk meg az Add függvény segítségével.
Paraméterek
string propertyName
A propertyName paraméterben kell megadnunk annak a property-nek a nevét, melyhez kötni szeretnénk az adatokat.
object dataSource
A dataSource paraméter adja meg az adatforrást.
string dataMember
A dataMember a dataSource adatforráson belül írja le annak az adathalmaznak a nevét, melyet a kontrol adott property-jéhez szeretnénk kötni.
Visszatérési érték
Visszatérési értékként kapunk egy Binding osztály példányát, mely a létrejött kapcsolatot írja le.
Add
Osztály: System.Windows.Forms.ControlBindingsCollection
public new void Add(
Binding binding
);
Új adatkapcsolat létrehozását valósíthatjuk meg az Add függvény segítségével.
Paraméterek
Binding binding
Az adatkapcsolat leírását egy Binding osztály létrehozott példányában kell megadnunk, melyet a binding paraméterben adunk át.
Létrehoztuk tehát a Table01 nevű adattáblát, és ezt szeretnénk a DataGrid-hez kötni. Ekkor az Add függvény első paraméterében a DataSource property nevét adjuk meg, mivel a DataGrid kontrolhoz e property-n keresztül köthető adat. A második paraméter az adatforrás lesz, mely a DataSet létrehozott példányát takarja. A harmadik paraméter az adatforráson belüli tábla lesz, mely Table01 néven került ott eltárolásra, mivel az egész adattáblát szeretnénk viszontlátni a DataGrid-ben.
    dataGrid1.DataBindings.Add("DataSource", ds, "Table01")
Kössük most a Table01 tábla Value nevű oszlopának adatait egy Label kontrolhoz. Ekkor az első paraméter a Text property neve lesz, mivel a Label kontrolnál ezen keresztül jeleníthetünk meg adatokat. A harmadik paraméter annyiban módosul, hogy most a Table01 tábla Value oszlopára kell hivatkoznunk. Nem is tehetnénk meg, hogy a Label-hez egy egész adattáblát rendelünk.
    label2.DataBindings.Add("Text", ds, "Table01.Value")
Az adattábla másik oszlopa, a Date hasonlóan kerül hozzákötésre egy DateTimePicker kontrol Value nevű property-jéhez.
    dateTimePicker1.DataBindings.Add("Value", ds, "Table01.Date")
Ha most elindítanánk a programot, akkor a lényeg már működne: minden kontrolban megjelenne az aktuális adat. A gond az lenne, hogy ha változtatjuk a DataGrid-ben az aktuális sort, akkor a többi kontrolban nem ennek az új sornak az adatai jelennének meg. Hogy szinkronizáljuk ennek működését, az alábbiakat kell tennünk. Kell először is egy esemény, mely akkor jön létre, ha a DataGrid aktuális sora esetlegesen megváltozik. Ehhez a CurrentCellChanged eseményt használjuk fel. Itt azt kell elérnünk, hogy a többi kontrol is az új értékeket mutassa. Mivel ezt nem végezhetjük el manuálisan, így más megoldást kell keresnünk. Szerencsére van egy olyan osztály is, mely az adatösszekötés vezérlését végzi. Ez a BindingContext osztály, mely egy kollekcióban tartja az összes adatkötést. Minden elemnek van egy Position property-je, melyen keresztül megtudhatjuk, hogy egy adott összekötésnek hányadik sora az aktuális. A Position property-n keresztül nem csak lekérdezhetjük ezt az információt, de módosíthatjuk is.
Ha tehát a DataGrid-ben másik sorra áll a felhasználó, akkor nincs más teendőnk, mint a Position property értékét megváltoztatnunk, méghozzá az alapján, hogy a DataGrid-nek hányadik sora az aktuálisan kijelölt.
  Private Sub dataGrid1_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dataGrid1.CurrentCellChanged
    Me.BindingContext(ds, "Table01").Position = dataGrid1.CurrentCell.RowNumber
  End Sub
A BindingContext osztályban van egy esemény is PositionChanged névvel, mely akkor jön létre, ha a Position property változik. További szinkronizációkhoz jól használható ez az esemény.
AddHandler Me.BindingContext(ds, "Table01").PositionChanged, AddressOf PositionChanged
Ha létrehozunk ehhez egy eseménykezelőt, akkor a sender paraméterében egy BindingManagerBase osztályt kapunk, melyet tetszés szerint felhasználhatunk.
  Private Sub PositionChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim bmb As BindingManagerBase = sender
    label4.Text = bmb.Position.ToString()
  End Sub
A továbbiakban nézzük, miként valósíthatunk meg speciális formátumú adatmegjelenítést és adatbevitelt. Hogy mikor is lehet szükségünk ilyenre, arra nézzük az alábbi példát: ha az adattáblában adott egy olyan számokat tartalmazó mező, melyben pénzértékeket tárolunk, akkor az adat megjelenítésénél szebb megoldás lenne az „1450” helyett az „1450 Ft” felirat megjelenítése az adott kontrolban. Ha az adat szerkeszthető is, például TextBox-hoz kötöttük, akkor viszont az is meg kell oldanunk, hogy ha a felhasználó begépeli a „254 Ft” szöveget, akkor ez értelmezhető legyen és a beírt szövegből a 254, mint szám az adattáblánk megfelelő helyére kerüljön.
Természetesen ilyen feladat nem csak pénzösszegnél fordulhat elő, hanem bármilyen más, akár egyedi formázásnál is.
Két feladat adott tehát: az egyik, mely az adattábla adatát a megfelelő formára konvertálja, és egy másik, mely a felhasználó által beírt egyedi formátumot visszaalakítja az adattáblában tárolt adat formájára.
A mellékelt példában ennek bemutatására feltettünk a Form-ra egy TextBox-ot, melyhez a Table01 Value nevű, Int32 típusú adatát szeretnénk kötni. Az egyedi formázást úgy valósítjuk meg, hogy a megjelenítendő adat elé egy „tc: ” feliratot helyezünk. Ennek értelme nincs, de jól szemlélteti a fenti probléma megoldását. Ettől kezdve tehát a Value oszlop adatai úgy jelennek meg a TextBox-ban, hogy minden szám elé a „tc: ” felirat kerül. Ha a felhasználó változtat az adaton, akkor ott is elfogadott a „tc: ” előtag, melyet nyilván vissza kell alakítanunk az adattároláshoz az eredeti formára.
E két feladat elvégzéséhez a Binding osztály két eseményt tart fenn.
Format
Osztály: System.Windows.Forms.Binding
public event ConvertEventHandler Format;
A Binding osztály Format eseménye akkor jön létre, ha a felhasználó számára szükséges adatot meg kell jeleníteni. Ekkor az adaton egyedi formázást végezhetünk el.
Parse
Osztály: System.Windows.Forms.Binding
public event ConvertEventHandler Parse;
A Binding osztály Parse eseménye akkor jön létre, ha a felhasználó által megadott adatot kell konvertálni az adat tárolásához szükséges formára. Ekkor a Format eseménynél elvégzett konverziót kell visszafelé elvégeznünk, hogy az eredeti formátum jöjjön létre.
Hozzunk tehát létre egy új adatkapcsolatot a TextBox számára, melyben felhasználjuk e két eseményt.
    Dim b As New Binding("Text", ds, "Table01.Value")
    AddHandler b.Format, AddressOf BindingFormat
    AddHandler b.Parse, AddressOf BindingParse
    textBox1.DataBindings.Add(b)
A Format eseménykezelőjénél első lépésben azt kell ellenőriznünk, hogy a kapott adatot, ha sztringgé konvertáljuk, megfelelő lesz-e az alkalmazásunk számára. Ehhez a paraméterként kapott ConvertEventArgs DesiredType-ét kell ellenőriznünk. Ezt követően a Value property-ből kiolvasott aktuális érték elé a „tc: ” előtagot illesztjük, és máris készen van a szükséges formázás: az adat megjelenhet a felhasználó számára.
  Private Sub BindingFormat(ByVal sender As Object, ByVal cevent As ConvertEventArgs)
    If cevent.DesiredType Is GetType(String) Then
      Dim i As Int32 = Convert.ToInt32(cevent.Value)
      cevent.Value = "tc: " + i.ToString()
    End If
  End Sub
Amikor a Parse esemény fut le, akkor a felhasználó változtatott a kontrolhoz kötött adaton, így nekünk vissza kell konvertálni az adatot annak tárolási formájára. Adott tehát most egy sztring, mely „tc: ” előtaggal kezdődik, azt pedig egy szám követi. Ahhoz, hogy a számot megkaphassuk, csak törölnünk kell az előtagot, majd a sztringet számmá alakítani.
    Private Sub BindingParse(ByVal sender As Object, ByVal cevent As ConvertEventArgs)
    If cevent.DesiredType Is GetType(Int32) Then
      Dim s As String = Convert.ToString(cevent.Value)
      cevent.Value = Convert.ToInt32(s.Remove(0, 4))
    End If
  End Sub

Cikksorozat

#IDKategóriaCikk címeSorozat
4397Windows.NET Framework konfigurálása az operációs rendszerben1. rész
4446Windows.NET Framework konfigurációs snap-in2. rész


Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |