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

Hasonló dokumentumok
2. Beadandó feladat dokumentáció

2. Beadandó feladat dokumentáció

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

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

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 5. előadás. Windows Forms alkalmazások párhuzamosítása. Cserép Máté

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

3. Beadandó feladat dokumentáció

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

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

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

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

Eseményvezérelt alkalmazások fejlesztése II 11. előadás. Window Runtime specifikus alkalmazások megvalósítása. Giachetta Roberto

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

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

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése. Giachetta Roberto

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

1. Beadandó feladat dokumentáció

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

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

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

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

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

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

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

Programozási technológia

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

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

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

Komponens alapú szoftverfejlesztés 8. előadás. Szoftver architektúrák alapvetései. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

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

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése

2. Beadandó feladat dokumentáció

3. Beadandó feladat dokumentáció

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

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

Johanyák Zsolt Csaba: Grafikus felület programozása. Copyright 2008 Johanyák Zsolt Csaba

Java Programozás 11. Ea: MVC modell

Vizuális programozás gyakorlat

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Általános szoftver architektúrák. Giachetta Roberto

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

2. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése I 12. előadás. Összetett szoftver architektúrák. Giachetta Roberto

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

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

Webes alkalmazások fejlesztése 10. előadás. Szolgáltatás alapú rendszerek megvalósítása (ASP.NET WebAPI) Cserép Máté

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

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.

BME MOGI Gépészeti informatika 7.

Szoftvertechnolo gia gyakorlat

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

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

A Microsoft Visual Studio 2005 fejlesztőkörnyezet

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

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

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).

Általános szoftver architektúrák

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

Programozási környezetek

OOP #14 (referencia-elv)

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

BME MOGI Gépészeti informatika 4.

Programozási technológia

A Java nyelv. Dialógus ablakok. Elek Tibor

Hozzunk létre két rekordot a táblában, majd véglegesítsünk (commit):

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

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

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

BME MOGI Gépészeti informatika 6.

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.

Eseményvezérelt alkalmazások fejlesztése II 3. előadás. Windows Forms dinamikus felhasználói felület, elemi grafika

Vizuális programozás gyakorlat

Események C#-ban Krizsán Zoltán iit

Java Programozás 3. Gy: Java GUI. Swing, AWT

Programozás BMEKOKAA146. Dr. Bécsi Tamás 10. Előadás

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

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

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

Programozás II. labor

Adatbázis alapú rendszerek gyakorlat Adatbázis alapú alkalmazásfejlesztés Java, C# környezetben

Webszolgáltatás és XML alapú adatbázis. 1. Az adatbázis megtervezése

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

Java Programozás 7. Gy: Java alapok. Adatkezelő 3.rész

Tájékoztató. Használható segédeszköz: -

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

Alap számológép alkalmazás

Webes alkalmazások fejlesztése 12. fejezet. Szolgáltatás alapú kommunikáció (WCF) Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Programozási technológia 2.

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

Eseménykezelés - Lottó játék

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

Grafikus felhasználói felület (GUI) létrehozása A GUI jelentése Egy egyszerű GUI mintaalkalmazás létrehozása

3. Határozza meg és írja ki a minta szerint, hogy a forrásállományban hány kémiai elem felfedezési adatai

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Vizuá lis prográmozá s

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

Elemi Alkalmazások Fejlesztése Beadandó Feladat Juhász Ádám

Java Programozás 8. Gy: Java alapok. Adatkezelő 4.rész

Java Programozás 6. Gy: Java alapok. Adatkezelő 2.rész

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

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Eseményvezérelt alkalmazások fejlesztése II 8. előadás Összetett WPF alkalmazások Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto

Az MVVM architektúra Az MVVM architektúrában a nézet tartalmazza a grafikus felületet és annak erőforrásait a nézetmodell egy közvetítő réteg, lehetőséget ad a modell változásainak követésére és tevékenységek végrehajtására a modell tartalmazza az alkalmazás logikáját a perzisztencia a hosszú távú adattárolást és adatelérést biztosítja View ViewModel Model Persistence ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:2

Függőség kezelés MVVM architektúrában Az architektúra akkor megfelelő, ha az egyes rétegek között minél kisebb a függőség (loose coupling) egyik réteg sem függhet a másik konkrét megvalósításától, és nem avatkozhat be a másik működésébe ennek eléréséhez függőség befecskendezést (dependency injection) használunk View ViewModel «abstraction» Model «abstraction» Persistence «realization» Model «realization» Persistence ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:3

Függőség kezelés MVVM architektúrában a nézetmodellt a nézetbe egy tulajdonságon keresztül fecskendezzük be (setter injection) a modellt a nézetmodellbe, a perzisztenciát a modellbe konstruktoron keresztül helyezhetjük (constructor injection) A programegységek példányosítását és befecskendezését az alkalmazás környezete (application environment) végzi ismeri és kezeli az alkalmazás összes programegységét (absztrakciót és megvalósítást is) nem az adott komponens, hanem a környezet dönti el, hogy a függőségek mely megvalósításai kerülnek alkalmazásra (Inversion of Control, IoC) ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:4

A környezet tevékenysége a környezetet egyszerű esetben megadhatja az alkalmazás (App), de használhatunk külön komponenst is a környezet hatásköre kibővíthető a globális, teljes alkalmazást befolyásoló tevékenységekkel (pl. időzítés) Environment View ViewModel «abstraction» Model «abstraction» Persistence «realization» Model «realization» Persistence ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:5

A környezet tevékenysége példányosítás, befecskendezés környezet adatkötés, parancskötés nézet változáskövetés nézetmodell metódus hívások visszatérési értékek, események események modell perzisztencia ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:6

Időzítés Időzítésre használhatjuk a System.Timer.Timer időzítőt, amely független a felülettől, így nem szinkronizál (a modellben) a DispatcherTimer felületi időzítőt, amely szinkronizál a felülettel (környezetben, vagy nézetmodellben) A tevékenységek szálbiztos végrehajtása (pl. modellbeli időzítő esetén) elvégezhető a Dispatcher.BeginInvoke( ) metódussal (az alkalmazásból), pl. Application.Current.Dispatcher. BeginInvoke(new Action(() => { textbox.text = "Hello World!"; })); ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:7

Példa Feladat: Készítsünk egy vizsgatétel generáló alkalmazást, amely ügyel arra, hogy a vizsgázók közül ketten ne kapják ugyanazt a tételt. a modell (ExamGeneratorModel) valósítja meg a generálást, tétel elfogadást/eldobást, valamint a történet tárolását, a modellre egy interfészen keresztül (IExamGenerator) hivatkozunk két nézetet hozunk létre, egyik a főablak (MainWindow), a másik a beállítások ablak (SettingWindow) a két nézetet ugyanaz a nézetmodell (ExamGeneratorViewModel) szolgálja ki, amelybe befecskendezzük a modellt ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:8

Példa a nézetmodell tárolja a start/stop funkcióért, beállítások megnyitásáért és bezárásáért felelős utasításokat a nézetmodell kezeli a modell eseményét (NumberGenerated), és frissíti a megjelenített számot a nézetmodell egy listában tárolja a kihúzott tételeket (History), ehhez létrehozunk egy segédtípus (HistoryItem), amely tárolja az elem sorszámát, illetve az állapotát (kiadható, vagy sem), ezeket a tulajdonságokat kötjük a nézetre az alkalmazás (App) felel az egyes rétegek példányosításáért, valamint a nézetmodell események kezeléséért ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:9

Példa Tervezés: App - _model :IExamGeneratorModel - _viewmodel :ExamGeneratorViewModel - _mainwindow :MainWindow - _settingswindow :SettingsWindow Application + App() - App_Startup(object, StartupEventArgs) :void - ViewModel_ApplicationMessaged(object, ApplicationMessageEventArgs) :void - ViewModel_OpenSettings(object, EventArgs) :void - ViewModel_CloseSettingsExecuted(object, EventArgs) :void - MainWindow_Closed(object, EventArgs) :void -_model «interface» Model::IExamGeneratorModel -_model -_mainwindow -_mainwindow Window View::MainWindow Window View::SettingsWindow Model:: ExamGeneratorModel -_viewmodel ViewModelBase ViewModel::ExamGeneratorViewModel ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:10

Példa Tervezés: HistoryItem - _model :IExamGeneratorModel - _periodcount :Int32 - _questioncount :Int32 + HistoryItem(Int32, Boolean) «property» + Number() :Int32 + IsChecked() :Boolean ExamGeneratorViewModel + ExamGeneratorViewModel(IExamGeneratorModel) - StartStop() :void - OpenSettings() :void - SaveSettings() :void - GenerateHistory() :void - Model_NumberGenerated(object, EventArgs) :void - OnApplicationMessaged(String, MessageType) :void - OnOpenSettingsExecuted() :void - OnCloseSettingsExecuted() :void «property» + Text() :String + QuestionNumber() :String + QuestionCount() :Int32 + PeriodCount() :Int32 + History() :ObservableCollection<HistoryItem> + StartStopCommand() :DelegateCommand + OpenSettingsCommand() :DelegateCommand + CloseSettingsCommand() :DelegateCommand «event» + ApplicationMessaged() :EventHandler<ApplicationMessageEventArgs> + OpenSettingsExecuted() :EventHandler + CloseSettingsExecuted() :EventHandler EventArgs ApplicationMessageEventArgs «property» + Message() :String + Type() :MessageType INotifyPropertyChanged ViewModelBase # ViewModelBase() # OnPropertyChanged(String) :void «event» + PropertyChanged() :PropertyChangedEventHandler DelegateCommand - _execute :Action<Object> {readonly} - _canexecute :Func<Object, Boolean> {readonly} «enumeration» MessageType Information Error ICommand + DelegateCommand(Action<Object>) + DelegateCommand(Func<Object, Boolean>, Action<Object>) + CanExecute(Object) :Boolean + Execute(Object) :void «event» + CanExecuteChanged() :EventHandler ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:11

Példa Megvalósítás (App.xaml.cs): private void App_Startup( ) { _model = new ExamGeneratorModel(10, 0); _viewmodel = new ExamGeneratorViewModel(_model); // a nézetmodell két nézetet is kiszolgál _viewmodel.opensettingsexecuted += new EventHandler(ViewModel_OpenSettings); _mainwindow = new MainWindow(); _mainwindow.datacontext = _viewmodel; } ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:12

Példa Megvalósítás (App.xaml.cs): private void ViewModel_OpenSettings( ) { if (_settingswindow == null) { // ha már egyszer létrehoztuk az ablakot, // nem kell újra _settingswindow = new SettingsWindow(); _settingswindow.datacontext = _ViewModel; // a beállításoknak is átadjuk a // nézetmodellt } _settingswindow.showdialog(); // megjelenítjük dialógusként } ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:13

Dinamikus felhasználói felület Bár a WPF is lehetőséget ad vezérlők dinamikus létrehozására, az MVVM architektúra miatt speciális megközelítést igényel a kódban nem hozhatunk létre vezérlőket, mivel a vezérlők megadása a nézet feladata a nézetben adjuk meg a generálandó vezérlőket egy gyűjteményben a gyűjteményt az ItemsControl vezérlő biztosítja, amely a megadott típusú elemeket (Item) tetszőleges tartalmazó vezérlőbe (ItemsPanel) helyezi el megadott módon (ItemContainer) az elemek típusát is a nézetben adjuk meg (pl. gomb, kép, de lehet egyedi osztály is) ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:14

Dinamikus felhasználói felület a nézetmodellben a generált vezérlőhöz tartozó függőségeket helyezzük egy típusba (amennyiben szükséges), majd ezeket egy felügyelt gyűjteménybe (ObservableCollection) csoportosítjuk DynamicField View +dynamicfields * - dynamiccontrol :ItemsControl «interface» INotifyPropertyChanged +DataContext ViewModel + dynamicfields :ObservableCollection<DynamicField> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:15

Dinamikus mezők A nézetmodellbeli osztály feladata egy vezérlő összes köthető tulajdonságát (pl. parancs, tartalom) egy helyen történő kezelése pl.: class DynamicField { // a dinamikus vezérlő megjelenése a // nézetmodellben public ICommand FieldCommand { get; set; } public String FieldText { get; set; } public Int32 X { get; set; } public Int32 Y { get; set; } // megadjuk a köthető tulajdonságokat } ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:16

Dinamikus felhasználói felület Az ItemsControl egy olyan vezérlő, amelyben tetszőleges sok, azonos típusú vezérlő helyezhető el az elemek sorrendje alapesetben oszlopfolytonos, azaz egymás alatt helyezkednek el (mint a WrapPanel-ben) a tartalmazott vezérlőre sablont adunk az ItemTemplate tulajdonsággal, vagyis megadjuk, milyen vezérlő jelenjen meg itt egy DataTemplate-t adunk meg, és abban a konkrét vezérlőt (pl. Button, TextBlock, Rectangle, ) az adatforrást az ItemsSource tulajdonságon keresztül köthetjük, az elemek száma az adatforrás darabszáma lesz ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:17

Dinamikus felhasználói felület Pl.: <ItemsControl ItemsSource="{Binding Fields}"> <!-- megadjuk az adatforrást --> <ItemsControl.ItemTemplate> <DataTemplate> <! megadjuk az elemek megjelenésének módját --> <Button Command="{Binding FieldCommand}" Content="{Binding FieldText}" /> <!-- gombokat helyezünk fel a rácsra, amelyek tartamát szintén kötjük --> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:18

Dinamikus felhasználói felület Az ItemsControl elrendezését felüldefiniálhatjuk az ItemsPanel tulajdonságban bármilyen panel megadható (pl. Grid, UniformGrid, Canvas, StackPanel, ) Pl.: <ItemsControl ItemsSource="{Binding Fields}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!-- tartalmazó vezérlő megadása --> <StackPanel Orientation="Horizontal" /> <!-- vízszintes tájolású elrendezés --> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:19

Példa Feladat: Készítsünk egy Tic-Tac-Toe programot, amelyben két játékos küzdhet egymás ellen. MVVM architektúrát használunk, külön projektet hozunk létre a nézetmodellnek (TicTacToeGame.ViewModel), valamint a nézetnek (TicTacToeGame.View) a mező típusában (TicTacToeField) megadjuk az elhelyezkedést, a parancsot, valamint a mező jelét karakterként a felületen gombokat (Button) helyezünk el egy fix méretű WrapPanel elrendezésben, a gombok feliratát módosítjuk a dinamikus felületet egy Viewbox-ba helyezzük, hogy a tartalom alkalmazkodjon az ablak méretéhez ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:20

Példa Tervezés: Window View::TicTacToeWindow Model::BasicTicTacToeModel -_model «interface» ViewModel::ITicTacToeModel INotifyPropertyChanged ViewModel::ViewModelBase -_model - _player :String ViewModel::TicTacToeField «property» + Player() :String + X() :Int32 + Y() :Int32 + FieldChangeCommand() :DelegateCommand App - _dataaccess :ITicTacToeDataAccess - _model :ITicTacToeModel - _viewmodel :TicTacToeViewModel - _window :TicTacToeWindow - _openfiledialog :OpenFileDialog - _savefiledialog :SaveFileDialog Application + App() - App_Startup(object, StartupEventArgs) :void - Model_GameWon(object, GameWonEventArgs) :void - Model_GameOver(object, EventArgs) :void - ViewModel_GameExit(object, System.EventArgs) :void «async» - ViewModel_LoadGame(object, System.EventArgs) :void - ViewModel_SaveGame(object, System.EventArgs) :void -_viewmodel ViewModel::TicTacToeViewModel - _model :ITicTacToeModel + TicTacToeViewModel(ITicTacToeModel) + SetTable() :void - Model_FieldChanged(object, FieldChangedEventArgs) :void - OnLoadGame() :void - OnSaveGame() :void - OnGameExit() :void «property» + NewGameCommand() :DelegateCommand + LoadGameCommand() :DelegateCommand + SaveGameCommand() :DelegateCommand + ExitGameCommand() :DelegateCommand + Fields() :ObservableCollection<TicTacToeField> «event» + GameExit() :EventHandler + LoadGame() :EventHandler + SaveGame() :EventHandler ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:21

Példa Megvalósítás (TicTacToeField.cs): public class TicTacToeField : ViewModelBase { private String _player; public String Player { get { return _player; } set { if (_player!= value) { _player = value; OnPropertyChanged(); } } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:22

Példa Megvalósítás (TicTacToeViewModel.cs): Fields.Add(new TicTacToeField { FieldChangeCommand = new DelegateCommand( param => { try { _model.stepgame( (param as TicTacToeField).X, (param as TicTacToeField).Y); // ha mezőre lépünk, akkor lépünk a // játékban } catch { } }) }); ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:23

Példa Megvalósítás (TicTacToeViewModel.cs): private void Model_FieldChanged(object sender, FieldChangedEventArgs e) { Fields.FirstOrDefault( field => field.x == e.x && field.y == e.y). Player = (e.player == Player.PlayerX)? 'X' : 'O'; // lineáris keresés a megadott sorra, // oszlopra, majd a játékos átírása } ELTE IK, Eseményvezérelt alkalmazások fejlesztése II 8:24