c# - WPF Binding with Notifyi does not update UI -


my issue ui not updated when propertychanged fired. xaml:

<listbox name="bookshelf" visibility="hidden" selecteditem="{binding selecteditem}" panel.zindex="1" height="auto" grid.column="3" margin="8,50,0,0" horizontalalignment="center"  itemssource="{binding bookshelf}" background="transparent" foreground="transparent" borderthickness="0" borderbrush="#00000000">             <listbox.itemtemplate>                 <datatemplate>                     <stackpanel verticalalignment="center" orientation="vertical">                         <textblock fontsize="14" margin="0,10,0,0" fontweight="bold" foreground="black" horizontalalignment="center" text="{binding path=dbid}" />                         <textblock fontsize="16" fontweight="bold" width="170" textwrapping="wrap" foreground="black" margin="5" horizontalalignment="center" text="{binding path=displayname}" />                         <image horizontalalignment="center" source="{binding path=bookimage}" width="200" height="200" margin="0,0,0,10" />                     </stackpanel>                 </datatemplate>             </listbox.itemtemplate>         </listbox> 

and:

<combobox margin="8,15,0,0" name="bookshelf_combobox" itemssource="{binding bookshelf}"     selecteditem="{binding selecteditem}" verticalalignment="center" horizontalalignment="center" displaymemberpath="displayname" height="22" width="140" visibility="visible" selectionchanged="bookshelf_combobox_selectionchanged"/> 

viewmodel:

public class bookshelfviewmodel : inotifypropertychanged {     public event propertychangedeventhandler propertychanged;     public event showcontentinbrowser showdatabasecontent;      public bookshelfviewmodel(showcontentinbrowser showmethod)     {         showdatabasecontent += showmethod;     }     private observablecollection<dbinfo> _bookshelf = new observablecollection<dbinfo>();     public observablecollection<dbinfo> bookshelf     {                 {             if (_bookshelf == null)                 _bookshelf = new observablecollection<dbinfo>();             return _bookshelf;         }         set         {             if (value != _bookshelf)                 _bookshelf = value;         }     }     private dbinfo _selecteditem { get; set; }     public dbinfo selecteditem     {                 {             return _selecteditem;         }         set         {             if (_selecteditem != value)             {                 _selecteditem = value;                 raisepropertychanged(new propertychangedeventargs("selecteditem"));                 if (_selecteditem == null)                     return;                 if (_selecteditem.relatedid != null)                     showdatabasecontent(_selecteditem, _selecteditem.relatedid);                 else                     showdatabasecontent(_selecteditem, _selecteditem.relatedid);              }         }     }     public void raisepropertychanged(propertychangedeventargs e)     {         if (propertychanged != null)             propertychanged(this, e);     } } 

this code i'm using setting datacontext , selecteditem:

await system.windows.application.current.dispatcher.begininvoke(          dispatcherpriority.background, new action(                 () => this.bookshelf.selecteditem = dbinfo          )       ); 

and datacontext:

await system.windows.application.current.dispatcher.begininvoke(          dispatcherpriority.background, new action(                 () => this.bookshelf.datacontext = bookshelfviewmodel          )        ); 

i'm new mvvm design , far have can tell articles have read, cant find what's wrong. i'm guessing using dispatcher not necessary don't think matters in case... listbox show objects updating selecteditem issue here...

update:

heres code dbinfo:

public class dbinfo {     public int relatedid { get; set; }     public string dbid { get; set; }     public tbase3.article currentarticle { get; set; }     public string linkid { get; set; }     public bool isarticle { get; set; }     public string folder { get; set; }     public bool isnamedarticle { get; set; }     public int currentblockindex { get; set; }     public int currentblockcount { get; set; }     public string displayname { get; set; }     public int vscrollpos { get; set; }     public int thtextversion { get; set; }     public bool ishtmltoc { get; set; }     public imagesource bookimage { get; set; } } 

reminder when ever set new value viewmodel -> selecteditem , goes propertychanged(this, e); line. not selected dbinfo selected in listbox.

update2:

i got right side of window list of books, book shelf many books in it. shows book scroll. book selected content being shown in window. if reason want change book code-behind, updates content webbrowser not update listbox book selecteditem

answer: okay found answer right now. code set bookshelf.selecteditem = dbinfo should bookshelfviewmodel.selecteditem = bookshelfviewmodel.bookshelf.first(x => x.dbid == dbinfo.dbif);

await system.windows.application.current.dispatcher.begininvoke(dispatcherpriority.background, new action(() => this.bookshelf.datacontext = bookshelfviewmodel)); 

that not good, do this? reccomend use of galasoft mvvm light , usage of viewmodellocator, setting datacontext(avaliable through nuget).it provides viewmodelbase, propertychanged needs , works, may extend suit neeeds. sounds datacontext, may actual problem if propertychanged isn't raised.

edit:

as pointed out clemens mode=twoway in binding not needed here, default selecteditem property anyway, i'll leave example....

<combobox margin="8,15,0,0" name="bookshelf_combobox" itemssource="{binding bookshelf}"  selecteditem="{binding selecteditem, mode=twoway}" verticalalignment="center" horizontalalignment="center" displaymemberpath="displayname" height="22" width="140" visibility="visible">     <i:interaction.triggers>         <i:eventtrigger eventname="selectionchanged">             <command:eventtocommand command="{binding selecteditemchangedcommand}" passeventargstocommand="true"/>         </i:eventtrigger>     </i:interaction.triggers> </combobox> 

i noticed selectionchanged="bookshelf_combobox_selectionchanged" in code, "nasty", use event command instead, because tying viewmodel views cbox. code above execute command arguments included, add following viewmodel.

public icommand selecteditemchangedcommand{ get; set;}  // somewhere in code.. selecteditemchangedcommand = new relaycommand<selecteditemchangedcommand>(onselecteditemchanged);  protected void onselecteditemchanged(selecteditemchangedcommand e) {    // magic here! or why not call method setter of bound property? } 

the wpf cheat sheet nice compact list of types of bindings, handy, used have both @ wall , home, when learning wpf :)

hope helps

cheers

stian


Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

visual studio 2010 - Connect to informix database windows form application -

android - Associate same looper with different threads -