Winrt, gombok és mvvm
Első pillantásra úgy tűnik, hogy az MVVM sablon alkalmazásának ötlete, hogy megszüntesse a szétválasztott kódfájl tartalmát, csak olyan elemekre alkalmazható, amelyek értékeket generálnak. Ha a gombokról van szó, akkor a koncepció elkezd szétoszlani. A Button objektum kezdeményez egy Click eseményt. Ezt az eseményt külön kódfájlban kell feldolgozni. Ha a nézet modell valóban implementálja a gomb logikát (ami valószínűleg), az eseménykezelőnek meg kell hívnia a nézetmodell módszert. Az ilyen megoldás építészeti szempontból megengedett, de még mindig nehézkesnek tűnik.
Szerencsére a Click eseménynek van egy alternatívája, amely ideális az MVVM számára. Néha informálisan az úgynevezett "parancs interfész". ButtonBase osztály definiál egy tulajdonság nevű Command (ICommand típusú) és CommandParameter (objektum típusát), amely lehetővé teszi gomb tényleg keresik a kihívást, hogy a néző a modell segítségével az adatok kötelező.
A Command és CommandParameter tulajdonságokat a függőségi tulajdonságok támogatják; ez azt jelenti, hogy a kötések vevői lehetnek. A Command tulajdonság szinte mindig adatkötő vevő, a CommandParameter tulajdonság opcionális. Például használható egyetlen parancselemhez kötődő gombok megkülönböztetésére, és általában ugyanazokat a funkciókat hajtja végre, mint a Tag tulajdonság.
Tegyük fel, hogy olyan számológép alkalmazást írt, amelynek kernelét a DataContext tulajdonság által meghatározott reprezentációs modell formájában hajtja végre. Az XAML jelölésnél létrehozható a számológomb egy példánya az addíciós parancs végrehajtásához (+):
Ez azt jelenti, hogy a nézet modell tartalmazza az ICommand típusú CalculateCommand tulajdonságot. amely valószínűleg a következőképpen definiálható:
A nézet modellnek inicializálnia kell a CalculateComnand tulajdonságot, megadva egy olyan példányt, amely az ICommand interfészt megvalósító osztály, amely a következőképpen van meghatározva:
Ha ezt a gombot kattintja, a CalculateCommand által hivatkozott objektum végrehajtási módját az "add" argumentummal hívják. Kiderül, hogy a Gomb közvetlenül kezeli a hívást (vagy inkább az Execute módot tartalmazó osztályba).
Az ICommand interfész másik két tagja egy bizonyos parancs végrehajtásának lehetőségét ellenőrzi. Ha a parancs jelenleg érvénytelen (például a számológép nem tudja végrehajtani a hozzáadást a megadott szám hiányában), akkor a megfelelő gombot le kell zárni.
A mechanizmus működik: az XAML elemzésének és betöltésének futtatásakor a Button objektum Command tulajdonsága kötelező (ebben a példában) a CalculateCommand objektumra. Gomb hozzárendel egy kezelőt a CanExecuteChanged eseményhez, és felhívja az objektum CanExecute metódust az "add" argumentummal (ebben a példában). Ha a CanExecute hamis, akkor a Gomb gomb megakadályozza magát. A jövőben a Gomb ismételten felhívja a CanExecute-t, amikor a CanExecuteChanged eseményt aktiválják.
Ha parancsot szeretne hozzáadni a nézetmodellhez, meg kell adnia egy olyan osztályt, amely végrehajtja az ICommand felületet. Az ilyen osztálynak azonban valószínűleg hozzá kell férnie a reprezentációs modell osztályának tulajdonságaihoz, és fordítva.
Felmerül a kérdés: vajon ezek az osztályok kombinálhatók-e?
Elméletileg lehetséges, de csak akkor, ha ugyanazok az Execute és CanExecute módszerek használhatók az oldal összes gombjára; Ehhez minden gombnak egyedi értékű CommandParameter-nek kell lennie, amellyel azonosítható. De először szeretnék bemutatni egy szabványos módszert a parancsok végrehajtására egy prezentációs modellben.
Osztály DelegateCommand
Újraírjuk a SimpleKeypad alkalmazást. korábban létrehozva, hogy bemutatómodellt használjon a billentyűleütések felhalmozódására és formázott karakterlánc létrehozására. Az INotifyPropertyChanged felület végrehajtása mellett a nézet modell kezeli a parancsokat is az összes billentyűzet gombjairól. A kattintáskezelőkre már nincs szükség.
És most a probléma: hogy a nézet modell kezeli a gombparancsokat, az ICommand típusának egy vagy több tulajdonsága van; ez azt jelenti, hogy egy vagy több osztályra van szükség, amely végrehajtja az ICommand felületet. Az ICommand megvalósításához ezeknek az osztályoknak tartalmazniuk kell az Execute és CanExecute módszereket, valamint a CanExecuteChanged eseményt. Ebben az esetben a fenti módszerek teste minden bizonnyal kölcsönhatásba lép a reprezentációs modell többi részével.
A probléma megoldható az Execute és a CanExecute metódusok definiálásával a bemutató modell osztályában, különböző, egyedi neveken. Ezután egy speciális osztály van definiálva, amely végrehajtja az ICommand-ot, és közvetlenül felhívja a prezentációs modell módszereit.
Ezt a különleges osztályt gyakran a DelegateCommandnak hívják. Miután ránézett, számos különböző megvalósítást talál erre az osztályra vonatkozóan, beleértve a Microsoft Prism infrastruktúrájának megvalósítását, amely segíti a fejlesztőket az MVVM mintát a WPF (Windows Presentation Foundation) és a Silverlight programban. Az alábbiakban a megvalósításom.
Saját osztályom DelegateCommand implementálja az ICommand felületet; ez azt jelenti, hogy tartalmazza az Execute és CanExecute módszereket, valamint a CanExecuteChanged eseményt. De amint kiderül, a DelegateCommand-nak más módszerre van szüksége a CanExecuteChanged esemény kezdeményezéséhez. Ezt RaiseCanExecuteChangednek nevezzük. Mindenekelőtt meg kell határoznia az ICommand-t megvalósító felületet, és ezt a kiegészítő módszert tartalmazza:
A DelegateCommand osztály végrehajtja az IDelegateCommand felületet, és egyszerű (de hasznos) generikus küldötteket használ a Rendszer névtérben. Ezeket az előre meghatározott küldötteket cselekvésnek és Funcnek nevezik, és kapnak 1-16 érvet. A Func küldöttek visszaadják egy adott típusú objektumot, és a cselekvés delegáltjai nem. Cselekvési küldött
Az osztály elvégzi az Execute és a CanExecute módszereket, de ezek az implementációk egyszerűen a mezőkben tárolt módszereket hívják. A mezőket az osztálytervező tölti ki az elfogadott érvekkel.
Például ha egy számítási parancs létezik a nézetmodellben, akkor a CalculateCommand tulajdonság definiálható benne:
A nézet modell két módszert is definiál a következővel: ExecuteCalculate () és CanExecuteCalculate ():
A nézet modellosztály-konstruktor létrehozza a CalculateCommand tulajdonságot a DelegateCommand egy példányának létrehozásával e két módszerrel:
Most, hogy megértette az általános elképzelést, fontolja meg a billentyűzetkiosztási modellt. Beviteli és megjelenítési szöveg esetén a nézetmodell két tulajdonságot határoz meg: az InputString és a DisplayText formázott változata.
képviselet modell is meghatározza kétféle tulajdonságok IDelegateCommand AddCharacterCommand nevek (digitális és karakter billentyűk) és DeleteCharacterCommand. Ezek a tulajdonságok által létrehozott létre példányt DelegateCommand módszerek ExecuteAddCharacter (), ExecuteDeleteCharacter () és CanExecuteDeleteCharacter (). A CanExecuteAddCharacter () metódus nem létezik, mert a gépelés mindig érvényes.
Az ExecuteAddCharacter () metódus feltételezi, hogy a felhasználó által megadott karakter átadódik a paraméterben. Így egy parancs több gombon osztozik.
A CanExecuteDeleteCharacter () metódus csak akkor ad vissza true-t, ha vannak olyan karakterek, amelyek törölhetők; ellenkező esetben a törlés gombot le kell tiltani. De ez a módszer csak a kötés inicializálásakor szól, és csak akkor, ha a CanExecuteChanged esemény aktiválódik. Logic megindítása esetén tárolt set-módszer InputString (), amely összehasonlítja a visszaadott értékek CanExecuteDeleteCharacter előtt és után a változás a bemeneti karakterlánc.
Az XAML fájl létrehoz egy példányt a nézetmodernek erőforrásként, majd meghatározza a DataContextet a Grid-ban. Jegyezd meg a Command kötések egyszerűségét tizenhárom gombvezérlésre és a CommandParameter használatára numerikus és karakteres billentyűkkel:
A projekt legérzékenyebb része a szétválasztott kódfájl, amely most már nem tartalmaz semmiféle InitializeComponent hívást. A feladat befejeződött.
A Windows Runtime funkciók segítségével mobilalkalmazást indíthat egy online áruházhoz. Korábban, ha figyelembe vesszük a fejlődés a boltban az ASP.NET MVC, azt nem írják le a fontos részleteket arról, hogyan kell nyitni egy online áruház hivatalossá dokumentumok, létrehozva egy támogató szolgáltatások nyújtása, megszervezni a munkát a futárok, stb