Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Programozás III. MVVM Adatkötés I.
2
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
3
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
4
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
5
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
6
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.
7
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:
8
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="{…}"
9
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 });
10
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]
11
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.
12
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>
13
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
14
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}"/>
15
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...
16
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}"
17
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}"
18
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!)
19
Feladat
20
Feladat
21
Feladat
22
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)
23
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
24
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ú)
25
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
26
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ó
27
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!
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.