Eseményvezérelt alkalmazások fejlesztése II 7. előadás. WPF alkalmazások architektúrája. WPF alkalmazások architektúrája

Hasonló dokumentumok
Eseményvezérelt alkalmazások fejlesztése II 7. előadás. WPF alkalmazások architektúrája. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése II 8. előadás. Összetett WPF alkalmazások. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Eseményvezérelt és objektumorientált programozás

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Eseményvezérelt alkalmazások fejlesztése II 12. előadás. Objektumrelációs adatkezelés (ADO.NET) Giachetta Roberto

Entity Framework alapú adatbáziselérés 2

2. Beadandó feladat dokumentáció

2. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése II 9. előadás. WPF erőforrások kezelése. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Window Runtime alapismeretek. Windows Runtime alapismeretek A Windows Runtime

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET)

Swing GUI készítése NetBeans IDE segítségével

Grafikus felhasználói felületek. Dr. Szendrei Rudolf Informatikai Kar Eötvös Loránd Tudományegyetem. Programozási technológia I. Dr.

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET) Cserép Máté.

3. Beadandó feladat dokumentáció

Programozási technológia

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Xamarin alapismeretek. Xamarin alapismeretek. Xamarin alapismeretek. Xamarin alapismeretek

Programozási környezetek

WCF, Entity Framework, ASP.NET, WPF 1. WCF service-t (adatbázissal Entity Framework) 2. ASP.NET kliens 3. WPF kliens

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

Programozási technológia

és az instanceof operátor

Bánsághi Anna 2015 Bánsághi Anna 1 of 31

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Xamarin alapismeretek. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Access adatbázis elérése OLE DB-n keresztül

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Webes alkalmazások fejlesztése 10. előadás. Webszolgáltatások tesztelése (ASP.NET Core) Cserép Máté

Szoftvertechnolo gia gyakorlat

Ugráló gomb oktatási segédlet Ugráló gomb

Már megismert fogalmak áttekintése

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Window Runtime alapismeretek, Modern UI alapú alkalmazások.

Java Programozás 11. Ea: MVC modell

Webes alkalmazások fejlesztése 9. előadás. Webszolgáltatások felhasználása (ASP.NET Core &.NET Framework)

Vizuá lis prográmozá s

Vizuális programozás gyakorlat

OOP #14 (referencia-elv)

Eseményvezérelt alkalmazások fejlesztése II 9. előadás. Window Runtime alapismeretek, Modern UI alapú alkalmazások

Választó lekérdezés létrehozása

Vizuális programozás gyakorlat

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET Core) Cserép Máté

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Webes alkalmazások fejlesztése 9. előadás. Webszolgáltatások felhasználása (ASP.NET WebAPI)

Entity Framework alapú adatbáziselérés

Komponens alapú szoftverfejlesztés 9. előadás. Grafikus felületű alkalmazások architektúrái. Giachetta Roberto

Webes alkalmazások fejlesztése 2. előadás. Webfejlesztés MVC architektúrában (ASP.NET) Webfejlesztés MVC architektúrában Fejlesztés ASP.

Bánsághi Anna 2015 Bánsághi Anna 1 of 39

Osztálytervezés és implementációs ajánlások

Osztálytervezés és implementációs ajánlások

Interfészek. PPT 2007/2008 tavasz.

2. Beadandó feladat dokumentáció

Objektumorientált programozás C# nyelven

Sorosítás (szerializáció) és helyreállítás. 1. Bináris sorosítás és helyreállítás Szükséges névterek Attribútumok. 1.3.

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

components : IContainer dx : int dy : int tmidőzítő : Timer toolstripseparator1 : ToolStripSeparator tsmikilépés : ToolStripMenuItem

2. Beadandó feladat dokumentáció

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Előszó A Windows alkalmazásfejlesztés rövid története A Windows életútja A Windows 8 paradigmaváltása... 16

Webes alkalmazások fejlesztése 8. előadás. Webszolgáltatások megvalósítása (ASP.NET WebAPI)

3. Beadandó feladat dokumentáció

A szerzõrõl... xi Bevezetés... xiii

Webes alkalmazások fejlesztése. Bevezetés az ASP.NET MVC 5 keretrendszerbe

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

OOP: Java 8.Gy: Abstract osztályok, interfészek

Programozás III KIINDULÁS. Különböző sportoló típusok vannak: futó, magasugró, focista, akik teljesítményét más-más módon határozzuk meg.

Webes alkalmazások fejlesztése 2. előadás. Webfejlesztés MVC architektúrában (ASP.NET Core) Cserép Máté

Programozási alapismeretek 4.

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Webes alkalmazások fejlesztése 7. előadás. Autentikáció és autorizáció (ASP.NET)

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása

Java programozási nyelv 4. rész Osztályok II.

Osztályok. 4. gyakorlat

Programozási nyelvek Java

A C# programozási nyelv alapjai

Webes alkalmazások fejlesztése Bevezetés. Célkitűzés, tematika, követelmények. A.NET Core keretrendszer

C#, OOP. Osztályok tervezése C#-ban

Elemi Alkalmazások Fejlesztése II.

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Objektumrelációs adatkezelés (Entity Framework) Cserép Máté

Webes alkalmazások fejlesztése Bevezetés. Célkitűzés, tematika, követelmények. A.NET Core keretrendszer

JAVA PROGRAMOZÁS 2.ELŐADÁS

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása. Biztonságos adattípusok megvalósítása

Java V. Osztályszint. lyszintű ű tagok. Példányváltozó. Osztályváltozó. Általános Informatikai Tanszék Utolsó módosítás:

Alkalmazott Modul III 6. előadás. Objektumorientált programozás: öröklődés és polimorfizmus

Pénzügyi algoritmusok

Java és web programozás

Java-ról Kotlinra. Ekler Péter AutSoft BME AUT. AutSoft

ISA szimulátor objektum-orientált modell (C++)

Objektumorientált programozás C# nyelven

Java Programozás 5. Gy: Java alapok. Adatkezelő 1.rész

BME MOGI Gépészeti informatika 7.

Alkalmazott Modul III 6. gyakorlat. Objektumorientált programozás: öröklődés és polimorfizmus

Segítség a megoldáshoz: 1. Készítse el a Window-t az ábrának és az osztálydiagramnak megfelelően.

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Eseményvezérelt alkalmazások fejlesztése II 7. előadás A nézet rétegződése Grafikus alkalmazásoknál alapvető tervezési kérdés a felületi megjelenés, valamint a tevékenységek szétválasztása, vagyis a modell/nézet (Model/View, MV) architektúra használata WPF alkalmazásoknál igazából a nézet is két részre bonható, felületi (XAML) kódra és háttérkódra WPF alkalmazások architektúrája nézet (XAML) MV (WPF) felhasználó Giachetta Roberto nézet (háttérkód) modell groberto@inf.elte.hu http://people.inf.elte.hu/groberto ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:2 A nézet felbontása A nézeten belüli szeparációnak köszönhetően a felület megvalósítása elhatárolható két különálló részre: a háttérkód a programozó feladata, aki ért a kódhoz, eszköze: Microsoft Visual Studio a felületi kód a grafikus feladata, aki ért az ergonómiához, tervezéshez, eszköze: Microsoft Expression Blend Ehhez szükséges, hogy a felületi kód és a háttérkód hasonlóan szeparálhatóak legyenek, mint a modell és a nézet A modell/nézet/nézetmodell architektúra A modell/nézet/nézetmodell (Modell/View/Viewmodel, MVVM) célja, hogy teljes egészében elválassza a megjelenítést és a mögötte lévő tevékenységeket köszönhetően egy közvetítő réteg (nézetmodell) közbeiktatásának, amely a háttérkód feladatát veszi át nézet (XAML) MVVM azaz ne legyenek összekötések (pl. eseménykezelő-társítás), amelyek mentén kettejük munkája összeakadhat felhasználó nézetmodell modell ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:3 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:4 A modell/nézet/nézetmodell architektúra Az MVVM architektúrában a modell tartalmazza az alkalmazás logikáját (algoritmusok, adatelérés), önálló, újrafelhasználható a nézet tartalmazza a felület vezérlőit (ablakok, vezérlők, ) és az erőforrásokat (animációk, stílusok, ) a nézetmodell lehetőséget ad a modell változásainak követésére és tevékenységek végrehajtására Előnyei: a grafikus és a programozó tevékenysége elhatárolódik a nézet, illetve a nézetmodell könnyen cserélhető, módosítható anélkül, hogy a másikat befolyásolná A modell/nézet/nézetmodell architektúra Egyszerű alkalmazásoknál nem célszerű, mivel hosszabb tervezést és körülményesebb implementációt igényel Megvalósításához több eszközt kell használnunk: felület és nézetmodell közötti adattársítás (Binding) az adatokban történt változások nyomon követése a nézetmodellben (INotifyPropertyChanged) tevékenységek végrehajtása eseménykezelők használata nélkül, parancsok formájában (ICommand) a nézetmodellben Az architektúra tovább bővíthető a perzisztencia (adatelérés) réteg bevezetésével, így 4 rétegű architektúrát kapunk ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:5 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:6 1

A modell/nézet/nézetmodell architektúra A modell/nézet/nézetmodell architektúra megvalósulása nézet adatkötés, parancskötés változáskövetés nézetmodell metódus/tulajdonság hívások visszatérési értékek, események modell ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:7 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:8 Adatkötés Az adatkötés (data binding) során függőségeket adhatunk meg a felületen megjelenő elemek tulajdonságaira egy adott vezérlő valamilyen függőségi tulajdonságát (cél) tudjuk függővé tenni valamilyen objektumtól, vagy annak egy tulajdonságától (forrás) így közvetett módon (anélkül, hogy a konkrét vezérlőhöz hozzáférésünk lenne) tudunk egy tulajdonságot állítani pl. egy szövegdobozban tárolt szöveget kiírathatunk egy címkére cél (címke) függőségi tulajdonság (felirat) adatkötés forrás (szövegdoboz) tulajdonság (szöveg) Adatkötés A kötést (Binding) a függőségi tulajdonság értékeként hozzuk létre forrás objektum (Source, ElementName) és tulajdonság útvonal (Path) megadásával, pl.: <TextBox Name="textBoxName" /> <!-- forrás (szövegdoboz) --> <TextBlock Text="{Binding ElementName=textBoxName, Path=Text" /> <!-- cél (címke), mindig azt a szöveget jeleníti meg, ami a szövegdobozban van --> <Button Content="{Binding ElementName=textBoxName, Path=Text" /> <! cél (gomb) --> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:9 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:10 Adatkötés forrás lehet egy teljes objektum, vagy bármely tulajdonsága, vagy beágyazott tulajdonság, pl.: <TextBlock Text="{Binding ElementName=textBoxName, Path=Text.Length" /> <!-- a címke a szöveg hosszát jeleníti meg --> amennyiben egy névvel rendelkező felületi elemhez kötünk, az ElementName, más objektumok, erőforrások esetén a Source tulajdonsággal adjuk meg a forrást a forrás értéke implicit konvertálódik a cél tulajdonság típusára, vagy mi adjuk meg az átalakítás módját (az IValueConverter interfész segítségével) Adatkötés paraméterezése A kötés többféleképpen paraméterezhető, pl.: a kötés módja (Mode) lehet egyirányú (OneWay), kétirányú (TwoWay, ekkor mindkét objektum változása kihat a másikra), egyszeres (OneTime), a cél frissítése (UpdateSourceTrigger) lehet változtatásra (PropertyChanged), fókuszváltásra (LostFocus), <TextBox Name="textAnotherName" Text="{Binding ElementName=textBoxName, Path=Text, Mode=OneWay, UpdateSourceTrigger=LostFocus" /> <!-- egyirányú kötés fókuszváltásra --> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:11 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:12 2

Adatkötés objektumértékekhez Adatkötés a felületi vezérlők mellett tetszőleges objektumra, kódban is megadható kódban a cél DataContext tulajdonságának kell megadnunk a forrást a teljes forrás kötése esetén a felületi kódban egy üres kötést adunk meg, pl.: <TextBox Name="textBox" Text="{Binding" /> <!-- a kötést megadjuk a felületen, de tulajdonságait nem töltjük ki --> textbox.datacontext = "Hello DataBinding!"; // a forrást a kódban adjuk meg Adatkötés objektumértékekhez tulajdonság kötése esetén meg kell adnunk az útvonalat, pl.: class Person { public String FirstName { get; set; public String LastName { get; set; Person person = new Person { ; textbox.datacontext = person; // a forrás a teljes objektum lesz <TextBox Name="textBox" Text="{Binding Path=FirstName" /> <!-- megadjuk a kötött tulajdonságot, röviden: {Binding FirstName --> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:13 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:14 Adatkötés gyűjteményekre Az adatkötés gyűjteményekre is elvégezhető, ehhez olyan vezérlő szükséges, amely adatsorozatot tud megjeleníteni (pl. ItemsControl, ListBox, GridView, ) a vezérlők ItemsSource tulajdonságát kell kötnünk egy gyűjteményre (IEnumerable) pl.: <ComboBox Name="comboPersons" ItemsSource="{Binding" /> List<String> persons = new List<String> { ; combopersons.datacontext = persons; // a teljes lista megjelenik a legördülő // menüben Adatkötés tranzitivitása Az adatkötés tranzitív a logikai fán a gyerekelemekre, így a tulajdonságok a beágyazott elemekben is elérhetőek pl.: <StackPanel Name="panelPersons"> <TextBlock Text="{Binding FirstName" /> <!-- a FirstName-t kötjük hozzá --> <TextBlock Text="{Binding LastName" /> <!-- a LastName-t kötjük hozzá --> </StackPanel> panelpersons.datacontext = person; // az objektum két tulajdonsága jelenik meg a tranzitivitás szűkíthető a tulajdonság megadásával ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:15 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:16 Adatkötés öröklődése gyűjtemények esetén megadhatjuk az egyes elemek megjelenését ehhez módosítanunk kell az adatok megjelenítési módját a vezérlőben az elemsablon (ItemTemplate) módosításával, amely egy adatsablont (DataTemplate) fogad mind a teljes vezérlőre, mind az egyes elemek vezérlőire meg kell adnunk a kötést az adatsablon bármilyen összetett vezérlőt tartalmazhat pl.: List<Person> persons = new List<Person> {; combopersons.datacontext = persons; // az elemek már összetett objektumok Adatkötés öröklődése <ComboBox Name="comboPersons" ItemsSource="{Binding" > <ComboBox.ItemTemplate> <!-- megadjuk az elemek megjelenítésének módját --> <DataTemplate> <TextBlock Text="{Binding FirstName"/> <!-- minden elemnek a FirstName tulajdonsága jelenik meg --> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:17 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:18 3

Adatkötés a teljes felületre Az adatkötés egy teljes ablakra (Window) is elvégezhető az adatkötést kódban adjuk meg, ezért az ablakot is kódban kell példányosítanunk és megjelenítenünk, pl.: MainWindow window = new MainWindow(); window.datacontext = ; // adatkötés az ablakra window.show(); // ablak megjelenítése az alkalmazás (App) indulásakor (Startup) kell végrehajtanunk a tevékenységeket, pl.: public App() { // konstruktor Startup = new StartupEventHandler(App_Startup); // lekezeljük a Startup eseményt Adatkötés változáskövetéssel Ahhoz, hogy a cél tükrözze a forrás aktuális állapotát, követni kell az abban történő változásokat ehhez a forrásnak meg kell valósítania az INotifyPropertyChanged interfészt ekkor a megadott tulajdonság módosításakor kiválthatjuk a NotifyPropertyChanged eseményt, ami jelzi a felületnek, mely kötéseket kell frissíteni az esemény elküldi a megváltozott tulajdonság nevét, ha ezt nem adjuk meg, akkor az összes tulajdonság változását jelzi egyszerűsítésként felhasználhatjuk a CallerMemberName attribútumot, amely automatikusan behelyettesíti a hívó tag (tulajdonság) nevét ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:19 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:20 Adatkötés változáskövetéssel Adatkötés változáskövetéssel pl.: class Person : INotifyPropertyChanged { private String _firstname; public String FirstName { get { return _firstname ; set { if (_firstname!= value) { _firstname = value; OnPropertyChanged(); // jelezzük a változást public event PropertyChangedEventHandler PropertyChanged; // az esemény public void OnPropertyChanged( [CallerMemberName] String name = null) // ha paraméter nélkül hívták meg, a hívó // nevét helyettesíti be { if (PropertyChanged!= null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); // eseménykiváltás ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:21 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:22 Adatkötés változáskövetéssel a változáskövetés teljes gyűjteményekre is alkalmazható, amennyiben a gyűjtemény megvalósítja az INotifyCollectionChanged interfészt az ObservableCollection típus már tartalmazza az interfészek megvalósítását, ezért alkalmas változó tartalmú gyűjtemények követésére pl.: ObservableCollection<Person> persons = new ObservableCollection<Person> { ; combopersons.datacontext = persons; // amennyiben a gyűjtemény, vagy bármely // tagjának tulajdonsága változik, azonnal // megjelenik a változás Feladat: Készítsünk egyszerű grafikus felületű alkalmazást, amellyel megjeleníthetjük, valamint szerkeszthetjük hallgatók adatait. a felületen a hallgató keresztneve, vezetékneve és Neptun-kódja külön szövegdobozba kerül, és egy szövegcímkében megjelenik a teljes neve, ezeket adatkötéssel fogjuk a hallgatóhoz (Student) kötni, amely jelezni fogja a változást (INotifyPropertyChanged) a nézetmodellben helyet kap a változásfigyelő gyűjtemény (ObservableCollection), és annak feltöltése a nézet és nézetmodell társítása az alkalmazásban (App) történik ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:23 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:24 4

ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:25 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:26 Megvalósítás (Student.cs): class Student : INotifyPropertyChanged { public String FirstName { get { return _firstname; set { if (_firstname!= value) { _firstname = value; OnPropertyChanged(); OnPropertyChanged("FullName"); // megváltoztak a FirstName és // FullName tulajdonságok is Megvalósítás (App.xaml.cs): private void App_Startup() { MainWindow window = new MainWindow(); // nézet létrehozása StudentViewModel viewmodel = new StudentViewModel(); // nézetmodell létrehozása window.datacontext = viewmodel; // nézetmodell és modell társítása window.show(); ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:27 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:28 Megvalósítás (MainWindow.xaml): <ItemsControl ItemsSource="{Binding Students"> <!-- megadjuk az adatforrást --> <ItemsControl.ItemTemplate><DataTemplate> <!-- megadjuk az adatok reprezentációját --> <StackPanel Orientation="Horizontal"> <TextBox Text="{Binding FirstName" Width="100" Margin="5"/> <!-- adatkötés a tulajdonságokhoz --> </ItemsControl /> Parancsok Mivel az eseménykezelők összekötnék a felületet a modellel, nem használhatóak az MVVM architektúrában Az eseménykezelők helyettesítésére a nézetmodellben parancsokat (ICommand) használunk adattársítással kapcsolható vezérlőhöz, annak Command tulajdonságán keresztül megadják a végrehajtás tevékenységét (Execute), valamint a végrehajthatóság engedélyezettségét (CanExecute) a végrehajthatóság változását is jelzi (CanExecuteChanged) A parancsnak adható végrehajtási paraméter is (a vezérlő CommandParameter tulajdonságával) ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:29 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:30 5

Parancsok public class MyCommand : ICommand { public void Execute(object parameter){ // tevékenység végrehajtása (paraméterrel) Console.WriteLine(parameter); public Boolean CanExecute(object parameter){ // tevékenység végrehajthatósága return parameter!= null; public event EventHandler CanExecuteChanged; // kiválthatóság változásának eseménye Parancsok public class MyViewModel { // nézetmodell // parancs elhelyezése a nézetmodellben public MyCommand ClickCommand { get; set; <Button Content="Click Me" Command="{Binding ClickCommand" CommandParameter="Hello, world!" /> <!-- parancs megadása adatkötéssel, valamint paraméterrel --> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:31 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:32 Feladat: Módosítsuk az előző alkalmazást úgy, hogy lehessen felvenni új hallgatót. a felületen három szövegdobozban megadhatjuk a hallgató adatait, majd egy gomb segítségével felvehetjük őket az alkalmazásba ehhez létrehozunk egy új parancs osztályt, amely a hallgató felvételét végzi (StudentAddCommand), és a végrehajtáskor felveszi a listába az új hallgatót a parancsot tulajdonságként felvesszük a nézetmodellben magát az új hallgatót (NewStudent) is felvesszük a nézetmodellben, hogy lehessen mihez kötni a felületi adatokat ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:33 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:34 Megvalósítás (StudentAddCommand.cs): class StudentAddCommand : ICommand // parancs objektum { private StudentsViewModel _viewmodel; public void Execute(Object parameter) { _viewmodel.addnewstudent(); // új hallgató felvétele ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:35 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:36 6

Megvalósítás (MainWindow.xaml): <StackPanel DataContext="{Binding NewStudent" Orientation="Horizontal" Grid.Row="1"> <TextBox Text="{Binding StudentCode" Width="100" Margin="5"/> </StackPanel> <Button Content="Add student" Command="{Binding AddCommand" Margin="5" Grid.Row="2" /> <!-- parancs hozzákötése --> Parancsok a nézetmodellben Mivel egy alkalmazásban számos parancsra lehet szükség, nem célszerű mindegyik számára külön osztályt készíteni a parancsoknak egy tevékenységet kell végrehajtania, amely Action típusú -kifejezéssel is megadható, míg a feltétel egy Func típusúval a tényleges tevékenységet végrehajtó művelet elhelyezhető a nézetmodell osztályban, így nem kell külön osztályokba helyezni a kódot elég csupán egy parancs osztályt létrehoznunk (legyen ez DelegateCommand) a tevékenység végrehajtásához, és a tényleges tevékenységet a parancs példányosításakor -kifejezés formájában adjuk meg ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:37 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:38 Parancsok a nézetmodellben public class DelegateCommand : ICommand { private Action<Object> _execute; private Func<Object, Boolean> _canexecute; // tevékenység és feltétel eltárolása public DelegateCommand(Action<Object> execute){ _execute = execute; // tevékenység rögzítése public void Execute(Object parameter){ _execute(parameter); // tevékenység végrehajtása Parancsok a nézetmodellben public class MyViewModel : INotifyPropertyChanged // nézetmodell { // parancs elhelyezése a nézetmodellben public DelegateCommand MyCommand { get; set; ; public void Write(Object parameter) { Console.WriteLine(parameter); // tevékenység MyCommand = new DelegateCommand(x => Write(x)); // tevékenység tényleges megadása ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:39 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:40 Parancsok a nézetmodellben Parancsok végrehajthatósága A parancs bármikor jelezheti, hogy állapota megváltozott a CanExecuteChanged eseménnyel amennyiben nem végrehajtható, a vezérlő kikapcsolt állapotba kerül az eseményt egy megfelelő metódus segítségével válthatjuk (RaisePropertyChanged), vagy automatizálhatjuk az állapotfigyelést a CommandManager osztály RequerySuggested statikus eseménye segítségével automatikusan meghívja a rendszer, amikor beavatkozás szükségességét érzi (pl. ha valamilyen tevékenység fut a felületen) az egyik eseményt elfedhetjük a másikkal, ehhez az esemény feliratkozását/leiratkozását kell megváltoztatnunk ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:41 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:42 7

Feladat: Készítsünk egy egyszerű számológépet, amellyel a négy alapműveletet végezhetjük el, illetve láthatjuk korábbi műveleteinket is. az alkalmazást MVVM architektúrában valósítjuk meg a nézetmodell (CalculatorViewModel) tárolja a szöveges értéket (NumberFieldValue), az eddigi számításokat (Calculations), valamint a számítás parancsát (CalculateCommand), utóbbit egy általános parancsból (DelegateCommand) felépítve a nézetben (MainWindow) a végrehajtó gombokat társítjuk a parancshoz, amelynek paraméterként adjuk át a végrehajtandó műveletet ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:43 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:44 Megvalósítás (MainWindow.xaml): <Grid> <TextBox Name="_textNumber" Height="42" VerticalAlignment="Top" Text="{Binding NumberFieldValue, UpdateSourceTrigger=PropertyChanged" FontSize="28" TextAlignment="Right" FontWeight="Bold" /> <!-- a szövegdobozhoz úgy kötjük a tartalmat, hogy minden módosításra mentsen --> <Button Command="{Binding CalculateCommand" CommandParameter="+" Content="+" Height="60" /> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:45 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:46 Megvalósítás (CalculatorViewModel.cs): public CalculatorViewModel() { CalculateCommand = new DelegateCommand(param => Calculate(param.ToString())); private void Calculate(String operatorstring) { switch (operatorstring) { case "+": _model.calculate(value, Operation.Add); break; Speciális parancskötések A speciális egér és billentyű utasításokhoz a vezérlő InputBindings tulajdonságát használjuk, amibe helyezhetünk billentyűzetkötést (KeyBinding), megadva a billentyűt (Key), vagy billentyűkombinációt (Gesture) egérkötést (MouseBinding), megadva a gombot (MouseAction), vagy a kombinációt (Gesture) <Window.InputBindings> <!-- bemeneti kötések --> <KeyBinding Command="{Binding MyCommand" Gesture="CTRL+R" /> <!-- Ctrl+R billentyűkombináció kötése --> </Window.InputBindings> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:47 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:48 8

Egyedi vezérlők Lehetőségünk van egyedi vezérlők létrehozására öröklődéssel, vagy létező vezérlők összeállításával felhasználói vezérlővé (UserControl) vezérlőként felhasználható más vezérlőkben (külön adatkötései, erőforrásai lehetnek) a saját vezérlőket névtér hivatkozáson keresztül érjük el, pl.: <Window xmlns:view="clr-namespace:myapp.view" > <!-- megadjuk a névteret --> <view:mycontrol > <!-- példányosítjuk az egyedi vezérlőt --> </Window> Feladat: Készítsünk egy egyszerű számológépet, amellyel a négy alapműveletet végezhetjük el, illetve láthatjuk korábbi műveleteinket is. lehessen a billentyűzetet is használni a műveletek megadásához a fókuszt automatikusan állítsuk a szövegdobozra (ehhez a nézetben használnunk kell a FocusManager osztályt) a szövegdoboz szövegét teljesen kijelöljük, ehhez felüldefiniáljuk a szövegdoboz billentyűzetkezelését mivel ez nem végezhető el a nézetben, létrehozunk egy új vezérlőt a szövegdoboz leszármazottjaként (SelectedTextBox), amelyet felhasználunk a felületen ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:49 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:50 Megvalósítás (MainWindow.xaml): <Window.InputBindings> <!-- billentyűparancsok megfelelő paraméterrel --> <KeyBinding Key="Enter" Command="{Binding CalculateCommand" CommandParameter="=" /> <KeyBinding Key="Add" Command="{Binding CalculateCommand" CommandParameter="+" /> </Window.InputBindings> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:51 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:52 Megvalósítás (MainWindow.xaml): <view:selectedtextbox x:name="_textnumber" Height="42" VerticalAlignment="Top" Text="{Binding NumberFieldValue, UpdateSourceTrigger=PropertyChanged" FontSize="28" TextAlignment="Right" FontWeight="Bold" /> <Button Command="{Binding CalculateCommand" CommandParameter="+" Content="+" FocusManager.FocusedElement="{Binding ElementName=_textNumber" Height="60" /> Megvalósítás (SelectedTextBox.cs): private void SelectedTextBox_KeyUp(object sender, KeyEventArgs e){ switch (e.key) { case Key.Add: // az akcióbillentyűkre case Key.Subtract: case Key.Enter: case Key.Multiply: case Key.Divide: SelectAll(); // minden szöveget kijelölünk break; ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:53 ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:54 9

Architektúra programcsomagok Az alapvető MVVM támogató konstrukciók a nyelvi könyvtárban nem elegendőek a hatékony, gyors fejlesztésre interfészek vannak (pl. INotifyPropertyChanged, ICommand), de nincsenek ősosztályok, gyűjtőosztályok Több olyan programcsomag került forgalomba, amely az MVVM alapú fejlesztést megtámogatja, pl.: Microsoft Prism: támogatja a modul alapú fejlesztést, az MVVM architektúrákat, nézet-dekompozíciót és cserét MVVM Light Toolkit: támogatja az MVVM architektúrát, a többrétegű modellt, komponensek közötti üzenetküldést, alkalmazás környezet kialakítását ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 7:55 10