Programozás III. MVVM Adatkötés I..

Slides:



Advertisements
Hasonló előadás
HTML enhanced for web apps! Fodor Krisztián
Advertisements

Operációs Rendszerek I.
Programozás III OOP ALAPOK.
Tömbök C#-ban.
Az MVC tervezési minta 2. előadás.
Iratkezelő rendszer fejlesztése WPF alapokon
Adaptív megjelenítés a WPF layout rendszer segítségével.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Objective-C Memória kezelés
Öröklődés 2..
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Bevezetés a Java programozásba
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/12 C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
C# tagfüggvények.
Annotációk a Java 5 nyelvben Kozsik Tamás. Annotációk Módosítószavak bővítése A programszöveg elemeihez rendelhetők –Csomagokhoz, típusokhoz, metódusokhoz,
© Kozsik Tamás Csomagok. © Kozsik Tamás A program tagolása Típusdefiníciók (osztályok, interfészek) Metódusok Blokk utasítások Csomagok.
Delphi programozás 8. ELŐADÁS ADO ActiveX Data Objects.
VFP Form programozás Form szerkesztő elemei vezérlő elemek
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
P ROGRAMOZÁS I/O műveletek. S YSTEM.C ONSOLE A programjainknak fontos része a felhasználóval való kommunikáció. Adatokat kell kérni tőle, vagy közölnünk.
Objektumorientált tervezés és programozás II. 3. előadás
WPF alkalmazások fejlesztése az M-V-VM tervezési minta alapján
A program a „Tudáshasznosulást, tudástranszfert segítő eszköz-, és feltételrendszer kialakítása, fejlesztése a Műegyetemen” (TÁMOP /1/KMR )
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
V 1.0 Szabó Zsolt, Óbudai Egyetem, Programozási Paradigmák és Technikák Programozási eszközök Interfészek Generikus.
V 1.0 Szabó Zsolt, Óbudai Egyetem, Programozási Paradigmák és Technikák Programozási eszközök Interfészek Generikus.
Visual Basic 2008 Express Edition
Visual Basic 2008 Express Edition
Webalkalkalmazás fejlesztése ASP.NET-ben Krizsán Zoltán.
Programozás III. Grafikus felület API-k és összehasonlításuk
Számítógépes grafika I. AUTOCAD alapok
Számítógépes grafika I. AUTOCAD alapok 3. előadás.
DLL használata és készítése Feladat
Opencms modul fejlesztés Krizsán Zoltán. Modulok fajtái Nincs előírás, csak tipikus tennivalók: –Content type: új típus(oka)t vezet be. –Template: új.
TÁMOP /1-2F Informatikai gyakorlatok 11. évfolyam Windows Forms alkalmazás készítése Czigléczky Gábor 2009.
Programozás III ÖTLETEK A FELADATMEGOLDÁSHOZ. A HF-EK APROPÓJÁN Néhány javaslat: 1. Jó lenne, ha a feladatmegoldás előtt átnéznék az előadás-anyagokat.
Programozás III SWING. SWING ALKALMAZÁSOK (ISM.) Swing felületű, eseményvezérelt alkalmazás létrehozása: 1.JFrame alapú osztály létrehozása Szerepe: vezérlés.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
V 1.0 Programozás III. Grafikus felület API-k és összehasonlításuk WPF Hello World Fontosabb UI-elemek UI-elemek tartalommodelljei UI-elemek öröklődési.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
V 1.1 Programozás III. Felhasználóifelület-elemek fontosabb tulajdonságai, eseményei, metódusai XAML alapok.
V 1.0 Programozás III. XML XAML Adatkötés I.. V 1.0ÓE-NIK, 2014 XML (w3schools.com) Hierarchikus adatleíró formátum XML deklarációk + elemek + attribútumok.
V 1.0 Programozás III. Gyakorlás. V 1.0ÓE-NIK, 2014 Gyakorlás –Feladat: Tic Tac Toe játék –Szabályok: A játékosok felváltva teszik le a jelöléseiket.
A szoftver mint komplex rendszer: objektumorientált megközelítés.
Alkalmazásfejlesztés gyakorlat
Neumann János Informatikai Kar
Windows Presentation Foundation
ListBox CheckedListBox TextBox
„Designer-barát” játéklogika
Neumann János Informatikai Kar
Adatkötés Sablonokkal
Adatkonverziók Erőforrások
Programozás III. MVVM Adatkötés I..
MVVM – WPF.
Dependency Injection Tesztduplikátumok, Mock-ok, Fake-ek Feladat
Folyamatok.
Konverziós operátorok
Előadás másolata:

Programozás III. MVVM Adatkötés I.

MVVM elv View (XAML) View- Model BL Jelenleg: XAML + code behind (.xaml.cs) Általános cél: komponenseink legyenek egymástól függetlenek Problémák: a jelenlegi „logika” (code behind...) függ a GUI-elemektől... User input feldolgozásakor a „logika” tudja, hogy Textbox/Slider/NumericUpDown adja az inputot. A vezérlő nevét/típusát/tulajdonságát mind közvetlenül használja Outputnál ugyanígy: az értéket fixen egy Label/Textbox/kép/MessageBox/komplex ablak segítségével jeleníti meg Ez függőség, ennek elkerülésére: új réteg (új osztály)

MVVM = nincs közvetlen GUI-elérés View (XAML) View- Model SET BL EVENT ViewModel VM = new ViewModel(); VM.Income = 1000; VM.TaxPct = 10; VM.Prepaid = 50; this.DataContext = VM; [... később, pl egy kiíráskor ...] MessageBox.Show(VM.Result); Nincs név szerinti elérés – a logika nem tud semmit az UI-ról

MVVM = “ismeretlen” adatforrás View (XAML) View- Model BL ADATKÖTÉS GUI-elemek és VM értékek összekötése = adatkötés (get/set hívása automatikus) <TextBox Text=“{Binding Path=Income}” ... /> Forrásobjektum: DataContext / UI element  VM Forrásproperty: Income  VM.Income Célobjektum: TextBox (Dependency object!) Célproperty: TextBox.Text (Dependency property!) Beállítható még: Mód (OneWay, TwoWay, OneWayToSource, OneTime) Update ideje (Explicit, PropertyChanged, LostFocus) Konverter (ha a forrás-és céltulajdonság más típusú)

MVVM = a view eseményekre reagál View (XAML) 2. GET 3. GET View- Model BL 1. EVENT 2. EVENT A View nem tudja, hogy a ViewModel változott... Ezért a VM megvalósítja az INotifyPropertyChanged interfészt Ez egy „PropertyChanged” esemény implementálását írja elő A View feliratkozik erre A VM elsüti az eseményt, ha egy tulajdonság változik Így a View tudomást szerez a tulajdonságok változásáról  automatikus getter-hívás  a kötött property update-elődik

Ebben a félévben: eseménykezelők a Code Behindban View (XAML) View- Model BL 1. SET 2. SET A BL-t normál esetben a VM update-eli Jelenleg ezt nem mindig tartjuk Mert a „BL” nálunk gyakran a Code Behind...  nem jó Így a „BL-ben” VM referencia van Ilyenkor a VM nem tudja setelni a BL dolgait (mert Code Behind-ra nem tarthat referenciát) Áthidalás: a Code Behind feliratkozhat a VM PropertyChanged eseményére (de: a View vagy a BL miatt változott a tulajdonság?) Nem jó... a Code Behind egybefordul a Window-val: ha a VM-mel az adatot szeparáljuk, az még kevés, a logikát is szeparálni kéne a Window-tól!  BL külön lenne jó

Valódi MVVM = Teljesen elválasztott komponensek View (XAML) Model (BL és DATA) COMMAND View- Model COMMAND SET ADATKÖTÉS Event Valódi MVVM-ben a View a ViewModel-ben „tárolt” parancsokat is hívhat (az ICommand interfészt implementáló propertyk) Ezek a BL és/vagy a Model rész felé továbbítódnak A code behind majdnem mindig üres! Részletek: lásd MVVM light / PRISM … Ebben a félévben eventeket használunk, commandokat nem!

Adatkötés I. GUI-elemek valamelyik tulajdonságának kapcsolása egy másik objektumhoz Célok lehetnek: Amikor az objektum adatai változnak, az a GUI-elemen is automatikusan látszódjon Ha a GUI-elemben változtatunk, az objektum adatai is automatikusan változzanak Pl: Window vezérlőin jelenjenek meg a személy adatai: textBoxNev.Text  szemely.Nev checkBoxSzabadsagon.IsChecked  szemely.Szabadsagon checkBoxBeteg.IsChecked  szemely.Beteg

Adatkötés I. Pl: Hangerő slider: mellette Labelen jelenjen meg számmal, hogy mennyi az aktuális hangerő label.Content  slider.Value A rádiógombok csak akkor legyenek engedélyezettek, ha a checkbox be van pipálva radioButtonXXX.IsEnabled  checkBox.IsChecked Vagy, ha a rádiógombok közös tartalmazóban vannak: stackPanel.IsEnabled  checkBox.IsChecked

Adatkötés I. Pl: ListBoxban egy adott tömb elemei jelenjenek meg listBox.ItemsSource  tömb ListBox kerete vegye fel azt a színt, amilyen ki van jelölve listBox.BorderBrush  listBox.SelectedItem Adattípusok? ComboBoxban kiválasztott elem adatait akarom kiírni labelXXXX.Content  comboBox.SelectedItem XXXX tulajdonsága

Adatkötés I. Az adatkötésnek van célja és forrása Pl: Az adatkötési művelet forrása maga az adat, vagy annak egy (kizárólag publikus) tulajdonsága A cél a GUI-elem, illetve ennek az a tulajdonsága, amely az adattartamat használja majd Az adatkötés célja ún. függőségi tulajdonság (Dependency Property) kell hogy legyen (a legtöbb GUIelem-tulajdonság ilyen) Az adatkötés célja DependencyObject-utód lehet csak Pl: Window vezérlőin jelenjenek meg a személy adatai: textBoxNev.Text  személy neve Forrás: szemely.Nev Cél: textBoxNev.Text

XAML markupbővítők A XAML értelmezők számára az attribútumhoz való értékrendelés többnyire egy új string vagy stringből konvertálható primitív/objektum létrehozását jelenti Időnként más viselkedésre van szükség: Null értéket akarunk hozzárendelni Már létező objektumot akarunk hozzárendelni Statikus objektumot akarunk hozzárendelni Nem alapértelmezett konstruktorral létrehozott objektumot akarunk hozzárendelni Stb. Formátum: Egyedileg kell megtanulni a használatát Tulajdonság="{…}"

Adatkötés I. Megadása a XAML-ban a {Binding} markupbővítővel ElementName: forráselem (UI-elem) neve Path: forráselemen belüli tulajdonság elérési útja Alternatív formátum C# nyelvű leírás (ritkán használt) Window konstruktorban az InitializeComponent() után, vagy Loaded eseménykezelőben… <CheckBox Name="checkBoxEnabled" Content="Enable!"/> <TextBox Name="textBoxToEnable" IsEnabled="{Binding ElementName=checkBoxEnabled, Path=IsChecked}" /> "{Binding IsChecked, ElementName=checkBoxEnabled}" textBoxToEnable.SetBinding(TextBox.IsEnabledProperty, new Binding("IsChecked") { Source = checkBoxEnabled });

Adatkötés I. - Path megadásának formái A teljes forrás objektumot használjuk (ritka): Path=. Egyszerű tulajdonság elérése (a forráson belül): ElementName=checkBoxEnabled, Path=IsChecked Tulajdonságon keresztül elérhető objektum tulajdonságának elérésére: ElementName=listBox, Path=SelectedItem.Nev Indexelhető tulajdonság elemének elérésére: ElementName=listBox, Path=Items[0]

Feladat Pl: Hangerő slider: mellette Labelen jelenjen meg számmal, hogy mennyi az aktuális hangerő label.Content  slider.Value A rádiógombok csak akkor legyenek engedélyezettek, ha a checkbox be van pipálva radioButtonXXX.IsEnabled  checkBox.IsChecked Vagy, ha a rádiógombok közös tartalmazóban vannak: stackPanel.IsEnabled  checkBox.IsChecked A listboxos példa (border color) a következő miatt van kihagyva: A listboxban stringek kell hogy legyenek, listboxitem nem jó. A stringeket belepakolhatod kódból, ami csúnya, vagy editorból, ami bonyolult (mert nem listboxitemet kell hozzáadni, hanem szimpla stringet, tehát a listboxhoz hozzáadadndó elem típusválasztásánál ki kell keresni a system.string-et.) Vagy: belepakolhatod xamlból is, de akkor névtérmegadás kell. Ezt mondjuk akár meg is mutathatjuk, ha már említettük.

Adatkötés I. – függőségi tulajdonságok Adatkötés célja mindig ún. függőségi tulajdonság WPF sajátosság, a „szabályos” tulajdonságnál többet tud Az UI-elemek legtöbb, de nem minden tulajdonsága ilyen A függőségi tulajdonság az értékét nem feltétlenül a „szokásos” módon kapja, hanem: Adatkötésből Tartalmazó elemek tulajdonság-értékének „örökléséből” Animációból Stílusból, erőforrásból Rendszerbeállításból (témák, felhasználói beállítások) Erről azért beszélünk, mert függőségi tulajdonság kell hogy legyen a kötés CÉLja. Emeld ki, hogy a tartalmazó elemek azonos tulajdonságának értéke „megörökölhető”, mert ezen az elven működik a DataContext.

Adatkötés I. – függőségi tulajdonságok A függőségi tulajdonságoknak a dokumentációban (MSDN) van egy „Dependency Property Information” fejezetük Pl. FrameworkElement.Width:

Adatkötés I. - DataContext Adatkötés alapértelmezett forrása Ha nem adunk meg ElementName-et vagy forrást másmilyen módon, akkor a DataContextben lévő objektum a forrás A DataContext függőségi tulajdonság, azaz értéke a tartalmazóktól „örökölhető” Ezt gyakran felhasználjuk olyan esetekben, amikor több UI-elem ugyanannak az objektumnak tulajdonságaihoz kötődne NEM MINDEN függőségi tulajdonság értéke örökölhető a tartalmazóktól. (Ezt a függőségi tulajdonság definíciójában adod meg.) De speciel a DataContext igen. Any bindings that are defined without the source object being specified (via the Binding.Source property), will take the DataContext of the target object as the source.  <StackPanel Name="stackPanel" DataContext="{Binding ElementName=comboBoxSzemelyek, Path=SelectedItem}"> <Label Content="{Binding Nev}"/> <Label Content="{Binding Eletkor}" <Label Content="{Binding Orszag}"/> <Label Content="{Binding Varos}"/> </StackPanel>

Adatkötés I. – DataContext A DataContextet C# kódból is lehet állítani: XAML kód az adatkötésre: Forrás beállítása pl. Window Loading eseményben, gombnyomásra vagy bármikor máskor: <StackPanel Name="stackPanel" > <Label Content="{Binding Nev}"/> <Label Content="{Binding Eletkor}" <Label Content="{Binding Orszag}"/> <Label Content="{Binding Varos}"/> </StackPanel> Szemely sz = new Szemely("Péter", 12, "Magyarország", "Budapest"); stackPanel.DataContext = sz; A pirossal keretezett Labelek voltak a közös StackPanelben

Adatkötés I. – DataContext Adatkötés nemcsak egy forrásobjektum valamely tulajdonságához, hanem a teljes forrásobjektumhoz is lehetséges Nem adunk meg Path-t vagy Path=. Ha nem adunk meg forrást, DataContexten értődik a kötés public override string ToString() //Személy osztály ToString() { return nev + " (" + szuletesiEv + ")"; } public MainWindow() { InitializeComponent(); this.DataContext = new Szemely() { Nev = "Peti", SzuletesiEv = 1985 }; } Emeld ki: itt is implicit ToString() hívás történik! (Később nemigen fogjuk ezt a ToString() hívást kihasználni – tehát ne „szoktasd rá” őket, hogy így írassák ki az objektum összes adatát – inkább 1 adat->1label, mert a {Binding} megadásnál az adatkötő motor nem tudja a forrásobjektum változását detektálni, tehát nem fog a labelen kifrissülni, ha a háttérobjektummal bármit csinálsz – még akkor sem, ha a megfelelő értesítési mechanizmust is implementáltad. Ez elvileg említve lesz a következő diasorban is. DataTemplate lesz a megoldás -> köv órán.) <Label Content="{Binding}"/>

Feladat Pl: ListBoxban egy adott tömb elemei jelenjenek meg listBox.ItemsSource  tömb ComboBoxban kiválasztott elem adatait akarom kiírni labelXXXX.Content  comboBox.SelectedItem XXXX tulajdonsága Mindkettőhöz datacontext állítást fogunk használni, ezért vannak itt. Kapcsold össze a két feladatot, tehát az első alapján csinálhatsz comboboxban tömbelemek megjelenítését...

Adatkötés I. Az előző adatkötések egyirányúak voltak Lehetséges irányok: OneWay, TwoWay, OneWayToSource, OneTime, Default OneWay: a forrás változása változtatja a célt, de fordítva ez nem igaz OneWayToSource: cél változtatja a forrást, fordítva nem igaz TwoWay: a forrás változása változtatja a célt, és fordítva is OneTime: a forrás inicializálja a célt, de a további változtatásoknak nincs hatása <TextBox Text="{Binding Value, ElementName=slider, Mode=TwoWay}"

Adatkötés I. Mikor módosítjuk a forrást? TwoWay vagy OneWayToSource irányok esetén LostFocus: akkor változik a forrás, ha az adatkötött UI-elem elveszítette a fókuszt (TextBox Textnél alapértelmezés) PropertyChanged: akkor változik a forrás, ha az adatkötött UI-elem kötött tulajdonsága megváltozott (általában ez az alapértelmezés) Explicit: a forrás változtatása kódból váltható ki az UpdateSource() metódus hívásával Default: a tulajdonság alapértelmezett viselkedését (LostFocus/ProperyChanged/Explicit) használja <TextBox Text="{Binding Value, ElementName=slider, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Hibakeresés adatkötésben A hibákról az Output ablakban kapunk értesítést akkor, amikor az adatkötés működésbe lépne (az adat tényleges lekérésekor) A példában elrontott tulajdonságnevek szerepelnek (nem publikus tulajdonság esetén ugyanez a hibaüzenet!)

Feladat

Feladat

Feladat