wpf - How to use different behaviours in the same ViewModel? -
i have view designed long running tasks. has header , progress bar. model has text header , counter progress bar , totalamountofwork field. model has
public delegate void taskcompleted(string resultdescription); public event taskcompletedcopyingcompletedevent; public event action updateviewstate;
when counters change model invokes updateviewstate. viewmodel subscribed events , updates in it's turn view.
ok. have 2 classes intended copy files hard disk flash drive , 1 class intended diagnostic information retrieving , information should copied flash drive too.
i want use them in same viewmodel, can't figure out how avoid code repeating. can't figure out how make relying on proper object oriented design.
those 3 classes implement interface this:
interface ilongrunningtask { void dowork(); }
and can implement viewmodel taking ilongrunningtask argument.
but @ name of name of interface. looks generalized. seems wrong such abstraction.
ok. seems me viewmodel should take delegate in order invoke long running task. in case how viewmodel interact model updating it's properties?
//update now, model looks like:
public class filescopyingmodel : ifilescopier { protected int filescounttocopy; public int filescounttocopy { { return filescounttocopy; } set { filescounttocopy = value; invokeupdateviewstate(); } } protected int currentprogressvalue; public int currentprogressvalue { { return currentprogressvalue; } set { currentprogressvalue = value; invokeupdateviewstate(); } } public delegate void copyingcompleted(string resultdescription); public event copyingcompleted copyingcompletedevent; public event action updateviewstate; private readonly ifilescopier filescopier; protected filescopyingmodel() { } public filescopyingmodel(ifilescopier filescopier) { if (filescopier == null) throw new argumentnullexception("filescopier"); this.filescopier = filescopier; } protected static string getcurrentdatetime() { return datetime.now.tostring("dd.mm.yyyy hh.mm.ss"); } protected void invokecopycompletedevent(string resultdescription) { if (copyingcompletedevent != null) copyingcompletedevent(resultdescription); } protected void invokeupdateviewstate() { if (updateviewstate != null) updateviewstate(); } protected driveinfo getfirstreadyremovabledrive() { return driveinfo.getdrives() .firstordefault(driveinfo => driveinfo.drivetype == drivetype.removable && driveinfo.isready); } public void copy() { filescopier.copy(); } } public interface ifilescopier { void copy(); } public class kfilescopier : filescopyingmodel, ifilescopier { private string destinationkfilesdirpath; public new void copy() { //some code } private static string composedestinationkfilesdirpath(driveinfo drive) { //some code } } public class logsdircopier : filescopyingmodel, ifilescopier { public readonly string logsdirpath; public logsdircopier() { //some code } public new void copy() { //some code } private void internalcopylogsdir(string destinationpath) { //some code } private static void closestorer(zipstorer zipstorer) { //some code } private static string composedestinationarchivefilepath(string destinationpath) { //some code } private void determinelogfilescount() { //some code }
viewmodel interact infrastructure above this:
public class filescopyingviewmodel: screen { private readonly filescopyingmodel model; private readonly iwindowmanager windowmanager; public int currentprogress { { return model.currentprogressvalue; } } public int filescounttocopy { { return model.filescounttocopy; } } [importingconstructor] public longrunningviewmodel(ifilescopier copier) { model = copier filescopyingmodel; model.copyingcompletedevent += copyingcompletedhandler; model.updateviewstate += updateviewstatehandler; windowmanager = new windowmanager(); } private void updateviewstatehandler() { notifyofpropertychange(() => currentprogress); notifyofpropertychange(() => filescounttocopy); } private void copyingcompletedhandler(string resultdescription) { //some code } private void removedrivesafely() { //some code } private void promptejection(string result) { //some code } private void promptsuccessejection() { //some code } private void promptejectflasherror() { //some code } protected override void onactivate() { try { var copier = (ifilescopier) model; task.factory.startnew(copier.copy); } catch (exception ex) { //error handling } } }
these 2 classes use "copy" name of method. want add 1 more class similar behavior, seems it's method should named "collectdiagnosticinfo". or maybe can add class diagnosticinfocopier:ifilescopier , same. don't know, sixth sense suggests there smell of kind.
Comments
Post a Comment