c# - Preferred method for binding in MVVM, Data Template in Resources file or just DataContext in View itself? -


this 1 has got me stumped thought looked @ must missing something. have went off traditional mvvm pattern msdn magazine:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

while learning mvvm. copy of code , replace need today wanted build scratch , saw there may more thought. mvvm appeared not work bindings when used resource dictionary datacontext directly. question wants find other developers suggested use of binding find.

summary of question this: why 'datatemplate' in resource dictionary appear not work shown below direct 'datacontext' method view right away bindings?

is because doing mixture of code behind settings views in code behind. or potentially because of else. appears property , it's implementation set correct in viewmodel if set 'datacontext' directly in view's xaml, why not in resource dictionary? thought advantage of method set bunch of relationships @ once. curious if there other setting need done work. curious in main example of mvvm method use data templates yet appears there more setting them doing 'bindings' work.

what did not work me:

i attempted basic stuff in main window xaml, leaving of code out make simpler:

main window xaml:

<window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts" x:class="wpftesting12_2.mainwindow"         title="mainwindow" height="350" width="525">     <window.resources>         <resourcedictionary source="resources.xaml"/>     </window.resources>     <grid>         <dockpanel x:name="dockpanel">             <menu dockpanel.dock="top" height="30">                 <menuitem header="charting">                     <menuitem header="mvvmdatabound" x:name="mnudataboundseriesmvvmcharting" click="mnudataboundseriesmvvmcharting_onclick"/>                 </menuitem>             </menu>             <textblock height="5" background="black" dockpanel.dock="top" />             <dockpanel x:name="dockchildren" dockpanel.dock="bottom"/>         </dockpanel>     </grid> </window> 

main window code behind:

public partial class mainwindow : window     {          public mainwindow()         {             initializecomponent();              this.windowstate = windowstate.maximized;         }           private void mnudataboundseriesmvvmcharting_onclick(object sender, routedeventargs e)         {             view.databoundmvvmchart c = new databoundmvvmchart();              dockchildren.children.clear();             dockchildren.children.add(c);         }     } } 

resource dictionary:

<resourcedictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     xmlns:vw="clr-namespace:wpftesting12_2.view"                     xmlns:vm="clr-namespace:wpftesting12_2.viewmodel"                     >   <datatemplate datatype="{x:type vm:databoundmvvmchartviewmodel}">     <vw:databoundmvvmchart/>  </datatemplate>  <style targettype="menuitem">         <setter property="background" value="wheat"/>     </style>     <style targettype="menu">         <setter property="background" value="wheat"/>     </style>  </resourcedictionary> 

view databoundmvvmchart.xaml:

<usercontrol x:class="wpftesting12_2.view.databoundmvvmchart"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"               xmlns:local="clr-namespace:wpftesting12_2.viewmodel"              mc:ignorable="d"               d:designheight="300" d:designwidth="300">     <usercontrol.resources>         <resourcedictionary source="..\resources.xaml"/>     </usercontrol.resources>     <grid>         <dockpanel>             <menu dockpanel.dock="top">                 <menuitem header="testercontent"/>             </menu>             <label dockpanel.dock="bottom" width="300" x:name="label" height="50" foreground="blue" fontsize="24"  content="{binding path=hellostring}"/>         </dockpanel>     </grid> </usercontrol> 

viewmodel bind view above:

namespace wpftesting12_2.viewmodel {     class databoundmvvmchartviewmodel : inotifypropertychanged     {         private string _hellostring;          public string hellostring         {             { return _hellostring; }             set              {                 _hellostring = value;                 raisepropertychanged("hellostring");             }         }          public databoundmvvmchartviewmodel()         {             hellostring = "hello there viewmodel";         }          public event propertychangedeventhandler propertychanged;          protected void raisepropertychanged(string propertyname)         {             if (propertychanged != null)                 propertychanged(this, new system.componentmodel.propertychangedeventargs(propertyname));         }     } } 

okay binding fail in view yet resources of color come in. thinking did wrong code behind property right away. let's move on:

what did work:

magicially if add these 4 lines view:

add declarations in 'usercontrol' segment @ top:

xmlns:local="clr-namespace:wpftesting12_2.viewmodel" 

then set reference usercontrol's datacontext:

<usercontrol.datacontext>         <local:databoundmvvmchartviewmodel/>     </usercontrol.datacontext> 

its important realize when working wpf there 2 layers: data layer (datacontext) , ui layer (the xaml).

bindings used pull data data layer view layer.

when write

<usercontrol.datacontext>     <local:databoundmvvmchartviewmodel/> </usercontrol.datacontext> 

you telling wpf should create new instance of databoundmvvmchartviewmodel , use data layer of usercontrol.

when write

<label content="{binding hellostring}" /> 

you telling label in data layer (the datacontext) property called "hellostring", , use content property.

if property "hellostring" not exist in data layer (which not unless set datacontext did <usercontrol.datacontext>), binding fail , nothing gets displayed except binding error in output window.

your datatemplate resourcedictionary different datacontext.

in fact, resourcedictionary sounds - dictionary of resources wpf can use in application when needed. objects in dictionary not default part of application's ui itself. instead, need referenced in way used.

but datatemplate

<datatemplate datatype="{x:type vm:databoundmvvmchartviewmodel}">     <vw:databoundmvvmchart/> </datatemplate> 

wpf uses datatemplates know how draw specific types of objects. in case, datatemplate telling wpf anytime needs draw object of type databoundmvvmchartviewmodel, should using databoundmvvmchart.

to insert object ui, content property used, such as

mylabel.content = new databoundmvvmchartviewmodel(); 

or

<contentcontrol content="{binding somedataboundchartviewmodelproperty}" /> 

i started out learning mvvm exact same article linked in question, , had lot of trouble figuring out well, lead me doing little blogging wpf/mvvm aimed beginners me :)

if you're interested, have few blog articles wpf/mvvm may understand technology better.

as actual question:

preferred method binding in mvvm, data template in resources file or datacontext in view itself?

i prefer using datatemplate in .resources somewhere, ui not tied 1 specific datacontext.

this important when creating re-usable controls mvvm. example, if have calculatorusercontrol, , assigned datacontext in control such <usercontrol.datacontext>, never use calculatorusercontrol other datacontext other 1 created when control created.

so typically set datacontext entire application once @ startup, , use datatemplates tell wpf how draw different viewmodels or models in application.

my entire application exists in data layer, , xaml merely user-friendly interface interact data layer. (if want see code sample, check out simple mvvm example post)


Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -