Top Banner

of 12

Introduction to WPF With MVVM

Aug 07, 2018

Download

Documents

Heriberto MT
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 8/20/2019 Introduction to WPF With MVVM

    1/26

    Paul Grenyer © May 2011

    An Introduction to the Windows Presentation Foundation with theModel-View-ViewModel

    Part 1

    Paul Grenyer 

     After three wonderful years working with Java I am bak in the !" arena and ama#ed byhow things have hanged$ %hen I was working with !" &reviously it was with $'et 1$1 andas I return $'et ( is ready to go$ I started a new ontrat and my lient suggested that toget ahead of the game I should learn %indows Presentation )oundation *%P)+, the latestMirosoft framework for reating %indows deskto& *and web+ a&&liations$ It re&laes thelikes of %indows )orms on the deskto&$ -wo of the ma.or features of %P) are that it isrendered entirely on a om&uter/s gra&his ard and se&arates &resentation from&resentation logi$

    Manning is my &referred tehnial book &ublisher, so I bought the P) version of %P) In Ation with isual tudio 2003 4%P)InAtion5 and read it on my 6indle$ It is a greatintrodution to &roduing Gra&hial 7ser Interfaes *G7Is+ with %P), but I later disoveredthat although Model8iew8iewModel *MM+ is overed, the detail is not great$ -heMM &attern is similar to Martin )owler/s Presentation Model 4Presentation model5, butwhere the &resentation model is a means of reating a 7I &latform8inde&endentabstration of a view, MM is a standardised way to leverage ore features of %P) tosim&lify the reation of user interfaes$ )ortunately there is a great M' Maga#ine artilealled %P) A&&s %ith -he Model8iew8iewModel esign Pattern 4MM5 that e9&lains itsim&ly and in a fair amount of detail$

    CanonCanon - Any comprehensive list of books within a field.

    8 ditionary$om

    -o demonstrate %P) with MM I am going to inrementally develo& a small a&&liationwhih allows the user to searh an arhive of books$ -he a&&liation is alled !anon andthe soure ode 4oure!ode5 is available for download from my website$ I develo&ed!anon using isual tudio 2010 and $'et (, but %P) a&&liations an also be reatedwith isual tudio 2003 and $'et :$;$ I have assumed that the reader is following along$

    )ire u& isual tudio and reate a new %P) A&&liation alled !anon$

  • 8/20/2019 Introduction to WPF With MVVM

    2/26

    Paul Grenyer © May 2011

    Figure 1: Default WPF Application Window

     As with any normal window you should be able to minimise, ma9imise, resi#e and lose it$

    If you take a look at the &ro.et struture in isual studio you/ll see there a&&ear to be .usttwo soure files, App.xaml and MainWindow.xaml$ Atually there are four soure files$ If

    you use the arrow ne9t to eah file to e9&and it you will see that eah $xaml  file has a

    orres&onding $cs  file= App.xaml.cs  and MainWindow.xaml.cs$ I/ll e9&lain the

    relationshi& between all four files shortly, but first I want to &ut all views into a View folder

    and the view names&ae$ In isual tudio, reate a &ro.et level folder alled View and

    move MainWindow.xaml into it$ MainWindow.xaml.cs will ome along with it$ -hen go

    into MainWindow.xaml.cs  and hange the names&ae from Canon  to Canon.View$

    -hen go into MainWindow.xaml  and modify the x:Class  attribute of the Window

    element so that it reads=

  • 8/20/2019 Introduction to WPF With MVVM

    3/26

    Paul Grenyer © May 2011

    idebar= Adding %P) A&&liations to oure !ontrol

     As with most isual tudio solutions you need to ensure you hek in all soure files,and not binaries or other build artefats$ oure file inlude the .xaml  and .xaml.cs

    files$

    WPF Project Structure

    %P) uses >AM? *&ronouned zammel +, whih stands for eXtensible A&&liation Marku&Language, to layout 7ser Interfaes *7Is+$ As we/ve seen all .xaml  files have a

    orres&onding xml.cs  soure file file$ In most  ases anything that an be defined in

    >AM? an also be written in !" and vie8versa$ AM? and others in !"$

    ?et/s start by taking a look at %P)/s e@uivalent to main, App.xml  and App.xml.cs,

    starting with App.xml:

    AM?$ %e/ll wantto hange this shortly when we in.et a view model$

    'ow that we understand how a %P) a&&liation is defined let/s take a look at how awindow is defined by e9amining MainWindow.xaml  and MainWindow.xaml.cs$

    :

  • 8/20/2019 Introduction to WPF With MVVM

    4/26

    Paul Grenyer © May 2011

    MainWindow.xaml  is in the View  folder we reated earlier$ Its name and loation

    orres&ond to the value of the StartupUri  attribute in the Application  element in

    App.xaml$ -herefore it is the first window that will be dis&layed$

  • 8/20/2019 Introduction to WPF With MVVM

    5/26

    Paul Grenyer © May 2011

    p',lic partial class %pp+  p',lic %pp  +  new MainWindow.&how3  --

    If you run the a&&liation again now *you need to add=

    'sin! Canon.)iew3

    of ourse+, you will see e9atly the same window$ All we/ve done is move the reation ofthe first window from >AM? to !"$ 'ow we have an instane of a window to in.et a viewmodel into$

     A view model need be nothing more om&le9 than a normal lass$ It does not re@uire anys&eial base lass, interfaes or members$ It/s .ust about the data$ !reate a &ro.et levelfolder alled ViewModel and reate the following lass in it *don/t forget to add it soure

    ontrol+=

    namespace Canon.)iewModel+  p',lic class MainWindow)iewModel  +  --

    very %P) view has a $ataContext  &ro&erty of ty&e o%&ect$ -his &ro&erty is null

    unless a view model is in.eted into the view$ %hen a view model is in.eted %P) seesthat $ataContext is no longer null and uses it$ %e/ll over an e9am&le of sim&le binding

    shortly$ -he $ataContext &ro&erty is also available within the view$ -his means the view

    knows about the view model it has, but the view model ontinues to know nothing aboutthe view that/s using it$ Bou an In.et the view model into the view by reating an instaneof it and setting the $ataContext &ro&erty on the view=

    p',lic partial class %pp+  p',lic %pp  +  new MainWindow

      +  4ataContext = new MainWindow)iewModel  -.&how3  --

    If you run the a&&liation again there will be no differene$ omething in the view must bebound to a &ro&erty in the model to see a differene in the 7I$

     A Slight Case of Over Binding 

  • 8/20/2019 Introduction to WPF With MVVM

    6/26

    Paul Grenyer © May 2011

    detail in %P) in Ation1$

    I think the best way to demonstrate binding is with a sim&le e9am&le$ In this one we/ll bindthe main window/s title to a &ro&erty in the view model$ ?et/s start off by adding the&ro&erty to the view model=

    p',lic class MainWindow)iewModel+  p',lic strin! %ppTitle  +  !et  +  ret'rn "Canon"3  -  --

    Cne the binding is in &lae the main window will dis&lay the string returned by theAppTitle &ro&erty$ -o bind the window title to the &ro&erty we have to modify the Title

    attribute of the Window element in MainWindow.xml from=

  • 8/20/2019 Introduction to WPF With MVVM

    7/26

    Paul Grenyer © May 2011

      8',lisher = strin!.mpt;3  1&59 = strin!.mpt;3  -

      p',lic oerride ,ool 'also,>ect o,>  +  if *eference'alsn'll? o,> ret'rn false3  if o,>.etT;pe @= t;peof5oo ret'rn false3

      ret'rn 'als5ooo,>3  -

      p',lic ,ool 'als5oo other  +  if *eference'alsn'll? other ret'rn false3  ret'rn 'als1d? other.1d3  -

      p',lic oerride int etashCode  +  ret'rn 1d.etashCode3  -

      --

    -his sim&le 'oo(  lass ontains a uni@ue nullable id for eah book, its title, author,

    &ublisher and I

  • 8/20/2019 Introduction to WPF With MVVM

    8/26

    Paul Grenyer © May 2011

    p',lic class &imple5oo*epositor; : 15oo*epositor;+  priate readonl; 1Aist

  • 8/20/2019 Introduction to WPF With MVVM

    9/26

    Paul Grenyer © May 2011

    -

    idebar= Simple'oo(Repositor)

    -he Simple'oo(Repositor) mok ob.et is fairly straight forward$ It &ersists a list of

    books in the %oo(s list=

    'ote that if the Searc*ields  method returns true  the Searc method knows it/s

    found a mathing book, sto&s iterating through the books and returns the urrent book$ Cfourse there might be multi&le mathes, but the Searc method only returns the first

    math$

    -he Save method an both u&date e9isting books and save new ones$ 'ew books are

    identified as having a null Id$ If the book being saved has an id and is already  in the

    book list, it is removed$ -his may seem a little odd$ owever, if the e9isting book is .ustadded to book list it will be in there twie$ Also remember that books are om&ared for

    e@uality by their ids$ AM?=

    Figure : !anon "ser Interface M# I

  • 8/20/2019 Introduction to WPF With MVVM

    10/26

    Paul Grenyer © May 2011

    -he first thing you might notie is that the !anon 7I is smaller than the default window&itured in figure 1$ -his is beause I modified the Window element in MainWindow.xaml

    to s&eify a starting height and width and a minimum height and width=

  • 8/20/2019 Introduction to WPF With MVVM

    11/26

    Paul Grenyer © May 2011

    -ool bars usually sit within a Tool'arTra) whih hel&s give them the usual %indows look

    and feel and an host multi&le tool bars$ -o insert the Tool'arTra) into the $oc(+anel

    you .ust make it a hild element$ Bou/ll notie that the Tool'arTra)  inherits the

    $oc(+anel.$oc( attribute from its &arent and uses it to s&eify that the Tool'arTra)

    should be dis&layed at the to&$ !hild ontrols inheriting &ro&erties from their &arents is aommon ourrene throughout %P) and makes for far less verbose >AM?$ %P) In

     Ation disusses this in more detail2$ -he Tool'ar is a hild of the Tool'arTra)$

    If you run the a&&liation again now you will see that the toolbar takes over the wholelient area of the window$ %e only want it to be a thin stri& aross the to& and we want therest of the area to be a !rid layout$ All we have to do is add a !rid to the $oc(+anel=

  • 8/20/2019 Introduction to WPF With MVVM

    12/26

    Paul Grenyer © May 2011

    maintains it$ -he button/s "s$e-ault attribute is also set to true as we want the searh

    button to be the default ation$ -he te9t bo9/s label is s&eified between the o&en andlosing elements$ -his is also @uite ommon for %P) ontrols$ If you run the a&&liationyou an enter te9t into the te9t bo9 and lik the button$ -he button does not do anythingyet as it does not have a ommand assoiated, I/ll disuss ommands in the ne9t setion$

    o far we/ve looked at the $oc(+anel and Stac(+anel layouts$ -hese are two of themost im&ortant %P) layouts, but by far the most useful and therefore the most ommonlyused layout is the !rid layout$ It has rows and olumns like any other grid and allows you

    to to &ut any ontrol in any sell or aross many ells$ In most ases rows and olumns aredefined using Row$e-inition and Column$e-inition  elements=

  • 8/20/2019 Introduction to WPF With MVVM

    13/26

    Paul Grenyer © May 2011

     

  • 8/20/2019 Introduction to WPF With MVVM

    14/26

    Paul Grenyer © May 2011

      : thisexec'te? n'll  +-

      p',lic *ela;Command%ctionect$ exec'te? 8redicateect$ canxec'te  +  if exec'te == n'll  +  throw new %r!'ment9'llxception"exec'te"3

      -

      this.exec'te = exec'te3  this.canxec'te = canxec'te3  - 

    4e,'!!er&tepThro'!hN  p',lic ,ool Canxec'teo,>ect parameter  +  ret'rn canxec'te == n'll 7 tr'e : canxec'teparameter3  -

      p',lic eent entandler Canxec'teChan!ed

      +  add + CommandMana!er.*e'er;&'!!ested G= al'e3 -  remoe + CommandMana!er.*e'er;&'!!ested E= al'e3 -  -

      p',lic oid xec'teo,>ect parameter  +  exec'teparameter3  --

    howing how it is used should &rovide enough e9&lanation of it for our &ur&oses$ If youwant to understand it in more detail see %P) A&&s %ith -he Model8iew8iewModel

    esign Pattern$ ome &eo&le reommend la#y loading Rela)Command ob.ets=

    priate *ela;Command OsaeCommand3p',lic 1Command &aeCommand+  !et  +  if OsaeCommand == n'll  +  OsaeCommand = new *ela;Command...3  -  ret'rn OsaeCommand3  -

    -

    but I really don/t see the need$ It/s a lot of e9tra ode, inluding a null hek and the

    &ro&erty is aessed as soon as the window is dis&layed and bound anyway$ o I .ust dothis=

    p',lic class MainWindow)iewModel+  ...  p',lic strin! &earchText + !et3 set3 -  p',lic 1Command *'n&earch+ !et3 priate set3 - 

    p',lic MainWindow)iewModel15oo*epositor; repo  +  ...  *'n&earch = new *ela;Commando =$ &earch? o =$ can&earch 3

    1(

  • 8/20/2019 Introduction to WPF With MVVM

    15/26

    Paul Grenyer © May 2011

      -

    priate ,ool can&earch  +  ret'rn @strin!.1s9'llPrmpt;&earchText3  -

      priate oid &earch

      +

      -  ...-

    -he getter of the RunSearc &ro&erty is &ubli so that it an be bound to, but the setter is

    &rivate so that it an only be set internally$ -he Rela)Command ob.et itself is reated in

    the view model onstrutor=

    *'n&earch = new *ela;Command o =$ &earch? o =$ can&earch 3

    -ake another look at the Rela)Command/s two &arameter onstrutor=

    p',lic *ela;Command%ctionect$ exec'te? 8redicateect$ canxec'te

    -he first &arameter is an Action delegate, whih ena&sulates a method that has a single

    &arameter and does not return a value$ A lambda e9&ression is used to s&eify the methodto all when the ommand is e9euted$ As it/s a delegate you ould do all sorts of in8lineommand im&lementations, but I find it learer to delegate to another method$ -he seond&arameter is a +redicate delegate, whih re&resents a method that defines a set of

    riteria and determines whether the s&eified ob.et meets those riteria$ A lambdae9&ression is used to s&eify a method that determines whether the ommand should beenabled$ *-he o &arameter is ignored as it is not needed in this senario+$ -o determine if

    the ommand should be enabled, we look to see if SearcText is not  null or is em&ty=

    priate ,ool can&earch+  ret'rn @strin!.1s9'llPrmpt;&earchText3-

    -he ne9t stage is to bind the ommand to the button$ -his is ahieved by by adding aCommand attribute to the searh 'utton element=

  • 8/20/2019 Introduction to WPF With MVVM

    16/26

    Paul Grenyer © May 2011

    disables de&ending on whether the te9t bo9 has ontent$ owever, when liked thebutton still does nothing$ In the ne9t setion we/ll look at finishing the binding and gettingbooks from the re&ository$

  • 8/20/2019 Introduction to WPF With MVVM

    17/26

    Paul Grenyer © May 2011

    ...

    -he -itle, Author, Publisher and I

  • 8/20/2019 Introduction to WPF With MVVM

    18/26

  • 8/20/2019 Introduction to WPF With MVVM

    19/26

    Paul Grenyer © May 2011

    4component &eifies that the assembly being referred to is referened from the

    loal assembly$

    0images0ligt%ul%.png -he relative &ath to the image file$

    Menus and Tool Bar Icons As it stands the !anon a&&liation is not very useful as it only allows us to searh for thetwo &reloaded books$ %hat it needs to be able to do ne9t is save u&dates to those booksand reate new ones$ ave ations are often invoked by a menu andLor tool bar button orvia a keyboard shortut$ 'e9t I/ll show you how to add a menu, with menu items bound toommands, whih share an ion with a tool bar button we/ll add to a new tool bar$ )irst adda menu to the to& setion of the dok &anel=

  • 8/20/2019 Introduction to WPF With MVVM

    20/26

    Paul Grenyer © May 2011

      ...  *'n&ae = new *ela;Commando =$ &ae? o =$ can&ae3  - 

    priate ,ool can&ae  +  ret'rn tr'e3  -

      priate oid &ae  +--

    -he canSave method .ust returns true for the time being$ %e/ll &ut it to better use later$

    Menu items an also have images and the same image an be used for a tool bar buttontoo$ Bou ould re&eat the loation of the image for both the menu item and the tool barbutton, but a better solution is to add a resoure=

    ?ey$%Sa=e4mage% 6riSo3r,e$%/Canon;,omponent/images/disk.png% /

      */+o,k-anel.Reso3r,es

  • 8/20/2019 Introduction to WPF With MVVM

    21/26

    Paul Grenyer © May 2011

      *B3tton Command$%{Binding R3nSa=e}%  *4mage So3r,e$%{Stati,Reso3r,e Sa=e4mage}% /

      */B3tton */ToolBar

  • 8/20/2019 Introduction to WPF With MVVM

    22/26

    Paul Grenyer © May 2011

      Pn8ropert;Chan!ed"Title"3  Pn8ropert;Chan!ed"%'thor"3  Pn8ropert;Chan!ed"8',lisher"3  Pn8ropert;Chan!ed"1&59"3  -  -

      ...  priate oid &ae  +  c'rrent5oo = repo.&aenew 5oo  +  1d = c'rrent5oo.1d?  Title = Title?  %'thor = %'thor?  8',lisher = 8',lisher?  1&59 = 1&59  -3  -

    -

    -o hold the referene we add a book field alled current'oo(  to the

    MainWindowViewModel$ %e default initialise it in the onstrutor to make sure it is valid

    even if a book has not been loaded yet$ -hen if we find a book when we searh for one weset the current'oo( referene to the new book$ )inally when we save the new book we

    use the "d from current'oo( to reate a new book instane$ After a suessful save we

    set current'oo( to the new book instane$ -ry it out and see if you an s&ot the further

    flaw$

    -he only way to reate a new book is to enter values into all the fields and save beforesearhing for a book and even then you an only do it one$ %hat we need is a new bookmenu item, image and tool bar button=

  • 8/20/2019 Introduction to WPF With MVVM

    23/26

    Paul Grenyer © May 2011

     

  • 8/20/2019 Introduction to WPF With MVVM

    24/26

    Paul Grenyer © May 2011

    Bou an of ourse add images and a orres&onding tool bar in the way already desribed$ere we/ve re&laed the ommand bindings with the system ommands for ut, o&y and&aste$ If you run the a&&liation you/ll find ut, o&y and &aste .ust work as e9&eted$%P) In Ation 4%P)InAtion5, the book in Introdued in &art 1, goes into the systemommands in more detail($

    'ot all system ommands are as straight forward$ 7nfortunately if you add the systemClose ommand to the file menu=

     

  • 8/20/2019 Introduction to WPF With MVVM

    25/26

    Paul Grenyer © May 2011

    "s$irt) is a boolean &ro&erty the indiates if any hanges have been made$ In the ase

    of AppTitle it is used to determine whether an asterisk should be a&&ended to the title

    when there are hanges and in the ase canSave  it is .ust returned to indiate if the

    ommand should be enabled$

    p',lic ,ool 1s4irt;

    +  !et  +  ret'rn  @c'rrent5oo.Title.'alsTitle JJ  @c'rrent5oo.%'thor.'als%'thor JJ  @c'rrent5oo.8',lisher.'als8',lisher JJ  @c'rrent5oo.1&59.'als1&593  --

    -he "s$irt) &ro&erty om&ares the urrent book fields against the e@uivalent 7I fields to

    determine if there are any hanges$ 7nfortunately this leads to some more verbosehanges to the 7I field &ro&erties to get the title and save ommand to u&date in real time=

    priate strin! title = strin!.mpt;3p',lic strin! Title+  !et  +  ret'rn title3  -  set  +  title = al'e3  Pn8ropert;Chan!ed"Title"3  PnChan!e3  --

    $$$priate oid PnChan!e+  Pn8ropert;Chan!ed"%ppTitle"3-

    I have only shown the hanges for the Title &ro&erty, but the Autor, +u%liser and

    "S'3 &ro&erties must be hanged in the same way$ Instead of using the default &ro&erty

    im&lementation we have to im&lement our own set method so that when the &ro&erty is

    u&dated we an tell %P) to also u&date the window title$ -his means we also need toseparately  store the &ro&erty value, whih is initialised to an em&ty string to math thedefault 'oo( instane, and im&lement a get method too$ Cne advantage is that we an

    also move the %P) notifiation that the &ro&erty has hanged to the &ro&erty itself so thatwe don/t need to remember to all n+ropert)Canged anywhere else in the ode

    where we assign the &ro&erty$ o the Update method is redued to=

    priate oid (pdate5oo ,oo+  c'rrent5oo = ,oo3

      Title = ,oo.Title3

      %'thor = ,oo.%'thor3  8',lisher = ,oo.8',lisher3  1&59 = ,oo.1&593-

    2;

  • 8/20/2019 Introduction to WPF With MVVM

    26/26

    Paul Grenyer © May 2011

    -he window title also needs to be u&dated when a book is saved as there are no longerany hanges=

    priate oid &ae+  c'rrent5oo = repo.&aenew 5oo

      +  1d = c'rrent5oo.1d?  Title = Title?  %'thor = %'thor?  8',lisher = 8',lisher?  1&59 = 1&59  -3  nC#ange!;-

    Finall# 

    -his is where this artile leaves the !anon a&&liation$ -here is more to do, but that falls

    outside the so&e of an introdutory artile$ ere I introdued you to sim&le %P) 7Idevelo&ment and the Model8iew8iewModel &attern inluding sim&le binding andommands$ -hen I demonstrated how to make %P) G7Is more aesthetially &leasingwith the use of images and more user friendly with the use of menus and toolbars andshowed how to im&lement those menus and toolbars with ustom and system ommands$

    In future artiles I will over unit testing and &atterns for maintaining the se&arationbetween the view model and the view when you want to dis&lay message bo9es and hildwindows or use ustom ontrols$

    %eferences4%P)InAtion5 %P) In Ation with isual tudio 2003 by Arlen )eldman and Ma99aymon$ Manning$ I