WPF MVVM update collections so that UI updates -
i want update ui. should use backgroundworker? put backgroundworker in mainwindowviewmodel , instantiate repositories again, or put in ordersqueueviewmodel , properties?
the ui displays contents of lists created linq. lists observablecollection
, properties of ordersqueueviewmodel. have viewmodel mainwindowviewmodel creates collection viewmodels, can bind collection mainwindow.xaml (view).
mainwindowviewmodel.cs:
public mainwindowviewmodel() { _printqueuerepos = new ordersprintqueuerepository(); _holdqueuerepos = new ordersholdqueuerepository(); _linestopickrepos = new linestopickrepository(); _linesperhourrepos = new linesperhourrepository(); //create instance of viewmodel , add collection ordersqueueviewmodel viewmodel = new ordersqueueviewmodel(_printqueuerepos, _holdqueuerepos, _linestopickrepos, _linesperhourrepos); this.viewmodels.add(viewmodel); }
mainwindow.xaml:
<window.resources> <datatemplate datatype="{x:type vm:ordersqueueviewmodel}"> <vw:ordersqueueview></vw:ordersqueueview> </datatemplate> </window.resources>
example of property in orderqueueviewmodel uses repository:
public observablecollection<linestopick> linestopick { { return new observablecollection<linestopick>(_linestopickrepos.getlinestopick()); } }
so havelinestopick
bound in ordersqueueview, , database updates lists should change in ui. i'v spent time reading backgroundworker, i'm not quite sure update lists. i'm hoping because observablecollections
can "refresh" them , use inotifypropertychanged , update ui automatically. new this, trying head around it, in advance help.
edit: using james's suggestion have ended in ordersqueueviewmodel. getting error "this type of collectionview not support changes sourcecollection thread different dispatcher thread", when code gets .clear() on 2 lists, thought dispatcher used for. suggestions?
action workaction = delegate { _worker = new backgroundworker(); _worker.dowork += delegate { linesthroughput.clear(); linestopick.clear(); //refresh linestopick foreach (var item in _linestopickrepos.getlinestopick()) { linestopick.add(item); } //refresh linesthroughput list<linesthroughput> lines = new list<linesthroughput> (_linesperhourrepos.getlinesthroughput()); foreach (var item in getlinesthroughput(lines)) { linesthroughput.add(item); } }; _worker.runworkerasync(); }; dispatcher.currentdispatcher.begininvoke(dispatcherpriority.normal, workaction);
you can either way - in mainwindowviewmodel or 1 of child view models. choose based on way produces lower coupling , higher cohesion between components. (lower coupling - fewer dependencies. higher cohesion - things go belong logically together.)
and backgroundworker reasonable technique. remember dispatch ui thread update collection. observablecollection code... needs work. don't reinstantiate observablecollection. this:
public observablecollection<linestopick> linestopick { get; private set; } // don't forget nstantiate in ctor public void refresh() { linestopick.clear(); foreach(var item in _linestopickrepos.getlinestopick()) { linestopick.add(item); } }
by keeping same observablecollection databound, ui automatically pick changes collection. if replace collection, lose binding , ui won't update until notify property containing collection changed. easier keep same collection.
Comments
Post a Comment