introduction to wpf with mvvm

Upload: heriberto-mt

Post on 07-Aug-2018

255 views

Category:

Documents


0 download

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