wpf - Debugging: Why a data-bound section breaks off when DataContext is reapplied? -


update 2010 06 12
distilled essence out smaller sample - solution available here http://db.tt/v6r45a4

it seems problem related tab control : when data context reapplied (click button), seems works expected. bindings refresh bindings on active tab broken.

you can verify selecting tab , clicking button, you'd see controls on tab go kaput. added bunch of logging statements how friend arrived @ synopsis , fix [ set datacontext="{binding}" on tab control ]

but we're still not sure why behaves way does...

tabcontrol data context set reprotabitembug.mainviewmodel tabpage [lefttabpage] data context set reprotabitembug.leftviewmodel system.windows.data error: 40 : bindingexpression path error: 'middleprop' property not found on 'object' ''mainviewmodel' (hashcode=50608417)'. bindingexpression:path=middleprop; dataitem='mainviewmodel' (hashcode=50608417); target element 'textbox' (name='middletabtextbox'); target property 'text' (type 'string') tabpage [middletabpage] data context set reprotabitembug.middleviewmodel middle tab textbox text changed 634272638824920423 tabpage [righttabpage] data context set reprotabitembug.rightviewmodel middle tab textbox text changed  

previous post (disclaimer: long post ahead... popcorn. i've spent part of day on this..)

my viewmodel composed of 3 poco subviewmodels. each subviemodel has properties bound in 3 sections mentioned above. each subviewmodel exposed standard .net get-only property (no inotifypropertychanged)

my view has 3 sections. each section has datacontext setter this..

... <tabitem  x:name="_tabpageforvm2"  datacontext="{binding propreturningsubvm2}">   <!-- followed ui items data-bound props inside sub-viewmodel --> </tabitem> ... 

so summarize

<mainview> <!--datacontext set programmmatically instance of mainviewmodel) -->    <control datacontext="{binding propreturningsubvm1}" >.. section1 .. </control>    <control datacontext="{binding propreturningsubvm2}" >.. section2 .. </control>    <control datacontext="{binding propreturningsubvm3}" >.. section3 .. </control> </mainview> 

now here's puzzling bit. on normal startup, create instance of mainviewmodel (which has child view models passed ctor). properties in watch window confirm this.

    trace.writeline("before setting datacontext");     mainview.datacontext = null;     mainview.datacontext = mainviewmodel;     //mainview.refresh();     trace.writeline("after setting datacontext"); 

everything works perfectly. due reasons beyond control, there scenario ui dismissed view still resides in memory. clear out when shown next time, create new instances of viewmodel , reapply datacontext (by calling same initialization routine before) when datacontext=mainviewmodel set executed, see bunch of binding errors in output window. interesting bindings inside 1 tab page (a sub view model) broken. other 2 sub view models function correctly - no binding errors.

system.windows.data error: 40 : bindingexpression path error: 'rphgaugemaxscale' property not found on 'object' ''mainviewmodel' (hashcode=38546056)'. bindingexpression:path=rphgaugemaxscale; dataitem='mainviewmodel' (hashcode=38546056); target element 'gauge' (name='gaugecontrol'); target property 'maxvalue' (type 'double') system.windows.data error: 40 : bindingexpression path error: 'rphgaugemaxscale' property not found on 'object' ''mainviewmodel' (hashcode=38546056)'. bindingexpression:path=rphgaugemaxscale; dataitem='mainviewmodel' (hashcode=38546056); target element 'gauge' (name='gaugecontrol'); target property 'majortickcount' (type 'int32') ... 

the properties exist on subviewmodel2, instead lookup using mainviewmodel.

next added refresh method on mainview (called after datacontext reapplied) this

    _tabpageforvm2.datacontext = null;     _tabpageforvm2.datacontext = mainvm.propreturningsubvm2; 

and fixes problem.

what puzzles me is

  • what special subvm2 ? if works first time datacontext assigned, why break second time around ?
  • i set header of tabpage {binding} check bound , showns "fulltypenameofsubvm2", indicates datacontext property of tab page being set. why bindings broken?

you can download snoop or other tool shows visual tree , see there content of tabitem not visual child of tabitem, visual child of tabcontrol.

alt text

so tabitem logical child of tabitem's content , tabcontrol visual child of tabitem's content. datacontext should inherited logical parent, seems me it's inherited randomly either tabitem or tabcontrol.

the best solution can suggest move bindings content so:

<tabitem x:name="lefttabpage" header="leftmodel">     <stackpanel orientation="horizontal" datacontext="{binding left}">         <my:gauge x:name="gauge" height="200" width="200" value="{binding leftprop}"/>         <viewbox height="200" width="200" >             <my:gauge x:name="scaledgauge" value="{binding leftprop}"/>         </viewbox>     </stackpanel> </tabitem>  <tabitem x:name="middletabpage" header="{binding}">     <textbox x:name="middletabtextbox" datacontext="{binding middle}" text="{binding middleprop}" /> </tabitem>  <tabitem x:name="righttabpage" header="rightmodel">     <textbox datacontext="{binding right}" text="{binding rightprop}"/> </tabitem> 

i think it. i'll try explain.

if second tab active(for example), middletabtextbox logical child of middletabpage , visual child of mytabcontrol (it has 2 different parents 2 different datacontexts). first tab not active , has logical child - stackpanel. when click button datacontext changes. , it's ok stackpanel - has 1 parent. middletabtextbox should do? shoult take datacontext visual or logical parent? seems logical context logical parent :) expeted behaviour, middletabtextbox gets visual child i.e. mytabcontrol. instead getting middleviewmodel mainviewmodel bunch of binding errors. don't know why wpf inherit datacontext visual parent not logical one.


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -