wpf - Notify parent ViewModel of changes in child ViewModels -
i have read few articles on here, describe how listen notifications raised. however: still having trouble apply application.
i have application several "pages".
one of pages contains wpf treeview control in along several viewmodels , data models.
public class folderssearchviewmodel { private readonlycollection<drivetreeviewitemviewmodel> _drives; public folderssearchviewmodel(string[] logicaldrives) { _drives = new readonlycollection<drivetreeviewitemviewmodel>( environment.getlogicaldrives() .select(s => new driveinfo(s)) .where(di => di.isready) .select(di => new drivetreeviewitemviewmodel(di)) .tolist() ); } public readonlycollection<drivetreeviewitemviewmodel> drives { { return _drives; } } }
this viewmodel contains drivetreeviewitemviewmodels , bound via datacontext usercontrol ("page").
the drive- , directorytreeviewitemviewmodel classes contain few attributes, otherwise based on treeviewitemviewmodel, can see here:
public class treeviewitemviewmodel : inotifypropertychanged { #region data static readonly protected treeviewitemviewmodel dummychild = new treeviewitemviewmodel(); readonly observablecollection<treeviewitemviewmodel> _children; readonly treeviewitemviewmodel _parent; bool _isexpanded; bool _isselected; #endregion // data #region constructors protected treeviewitemviewmodel(treeviewitemviewmodel parent, bool lazyloadchildren) { _parent = parent; _children = new observablecollection<treeviewitemviewmodel>(); if (lazyloadchildren) _children.add(dummychild); } // used create dummychild instance. private treeviewitemviewmodel() { } #endregion // constructors #region presentation members #region children /// <summary> /// returns logical child items of object. /// </summary> public observablecollection<treeviewitemviewmodel> children { { return _children; } } #endregion // children #region hasloadedchildren /// <summary> /// returns true if object's children have not yet been populated. /// </summary> public bool hasdummychild { { return this.children.count == 1 && this.children[0] == dummychild; } } #endregion // hasloadedchildren #region isexpanded /// <summary> /// gets/sets whether treeviewitem /// associated object expanded. /// </summary> public bool isexpanded { { return _isexpanded; } set { if (value != _isexpanded) { _isexpanded = value; this.onpropertychanged("isexpanded"); } // expand way root. if (_isexpanded && _parent != null) _parent.isexpanded = true; // lazy load child items, if necessary. if (this.hasdummychild) { this.children.remove(dummychild); this.loadchildren(); } } } #endregion // isexpanded #region isselected /// <summary> /// gets/sets whether treeviewitem /// associated object selected. /// </summary> public bool isselected { { return _isselected; } set { if (value != _isselected) { _isselected = value; this.onpropertychanged("isselected"); } } } #endregion // isselected #region loadchildren /// <summary> /// invoked when child items need loaded on demand. /// subclasses can override populate children collection. /// </summary> protected virtual void loadchildren() { } #endregion // loadchildren #region parent public treeviewitemviewmodel parent { { return _parent; } } #endregion // parent #endregion // presentation members #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; protected virtual void onpropertychanged(string propertyname) { if (this.propertychanged != null) this.propertychanged(this, new propertychangedeventargs(propertyname)); } #endregion // inotifypropertychanged members }
i have followed tutorial , ideas described in http://www.codeproject.com/articles/26288/simplifying-the-wpf-treeview-by-using-the-viewmode , works great far.
my problem is: i add string "selected" attribute folderssearchviewmodel, contain path of selected child viewmodel. drivetreeviewitemviewmodel , directorytreeviewitemviewmodel each have "path" property, contains full path child.
so: once onpropertychanged("isselected") called, notify folderssearchviewmodel , have method copy path-property selected treeviewitemviewmodel new "selected"(string) attribute.
i achieve passing folderssearchviewmodel-object children , children's children etc. in constructor - there no better way of doing this? suppose should hook folderssearchviewmodel propertychanged-event of every node , sub-node, know experience in mvvm in such case.
by way: use wpf treeview.selecteditem selected treeviewitemviewmodel, not sound right since want keep view, models , viewmodels separate.
p.s.: tried reading , making use of mvvm in wpf - how alert viewmodel of changes in model... or should i?, sadly not seem solve problem.
any appreciate!
the way mine works is, messenger service singleton discussed. use di, vm needs use gets imessengerservice instance injected it.
imessengerservice looks like:
public interface imessengerservice : iservicebase { message<t> getmessage<t>() t : imessagebase; }
message "param" classes available application wide, might have like:
public class folderopened : imessagebase { }
so, folderopened class available throughout application, defined @ compile time obviously.
any client care message subscribe message in vm constructor:
_messenger.getmessage().handler += ...
it doesn't matter if sender has "registered" yet, messenger based on message class type.
at time, can send message:
_messenger.getmessage().sendmessage(...);
ymmv, messenger automatically disconnect disposed / non existant subscribers, really, correct way vm unsubscribe in finalizer or dispose method.
does clear up?
Comments
Post a Comment