WPF Window closing confirmation in c# MEF context -


i tasked implementing simple confirmation dialog trying close main window of application, only while specific process running. closing application means aborting process. if process not running no confirmation needed.

at first created interface application.current.mainwindow , used closing event of that, teacher came else, can't find right way finish it.

there canclose method in code base use, empty default. it's in appinit class mainwindow opened. did in constructor this:

[importingconstructor]     public appinit(mainwindow mainwindow, [importmany] ienumerable<iclosingvalidator> closingvalidator)     {         this.mainwindow = mainwindow;         this.closingvalidator = closingvalidator;     } 

that idea of teacher. in canclose method can iterate through these closing validations , return true or false, so:

public boolean canclose()     {         foreach (var validation in this.closingvalidator)         {             var result = validation.canclose();              if (result == false)             {                 return false;             }         }          return true;     } 

the closingvalidator looks following, think wrong, need build dialog somewhere. whole thing works, flag indicating whether process in question running in viewmodel of project, meaning confirmation dialog shown.

 [export(typeof(iclosingvalidator))] [partcreationpolicy(creationpolicy.nonshared)] public class closingvalidator : iclosingvalidator {     private readonly imessagedialog messagedialog;     private readonly ioverlayeffect overlayeffect;      [importingconstructor]     public closingvalidator(imessagedialog messagedialog, ioverlayeffect overlayeffect)     {         this.messagedialog = messagedialog;         this.overlayeffect = overlayeffect;     }      public boolean canclose()     {         using (this.overlayeffect.apply())         {             var result = this.messagedialog.showdialog(                 new messagedialogargs(resources.resources.confirmclosingapplicationtitle,                                       resources.resources.confirmclosingapplicationmessage,                                       messageboxbutton.yesno,                                       messageboximage.systemquestion));              if (result == messageboxresult.yes)             {                 return true;             }         }          return false;     } 

i think question comes down this: where build dialog , how use boolean flag viewmodel determine whether show dialog in first place? i'm relatively new mef, sorry anything's unclear.

edit: think idea can use interface implement further closing validations @ point in future.

edit 3:

simplified viewmodel implementation (the actual viewmodel has many parameters):

[export] public class tocviewmodel {     [importingconstructor]     public tocviewmodel(measurementsequenceexecution measurementsequenceexecution)     {         this.measurementsequenceexecution = measurementsequenceexecution;     }          public boolean canapplicationclose     {         { return !this.measurementsequenceexecution.ismeasurementsequencerunning; }         set         {             this.measurementsequenceexecution.ismeasurementsequencerunning = !value;         }     } 

the iclosingvalidator implementation:

[export(typeof(iclosingvalidator))] [partcreationpolicy(creationpolicy.nonshared)] public class closingvalidator : iclosingvalidator {     [importingconstructor]     public closingvalidator()     {     }      public boolean canapplicationclose { get; } 

the iclosingvalidator interface:

public interface iclosingvalidator {     boolean canapplicationclose { get; } } 

the class handling closing:

[export(typeof(iapp))] public class appinit : iapp {     [importingconstructor]     public appinit(mainwindow mainwindow,                    [importmany(typeof(iclosingvalidator))] ienumerable<iclosingvalidator> closingvalidatorclients,                    ioverlayeffect overlayeffect,                    imessagedialog messagedialog)     {         this.mainwindow = mainwindow;         this.closingvalidatorclients = closingvalidatorclients;         this.overlayeffect = overlayeffect;         this.messagedialog = messagedialog;     }       public boolean canclose()     {         if (this.closingvalidatorclients != null)         {             foreach (var client in this.closingvalidatorclients)             {                 if (!client.canapplicationclose)                 {                     using (this.overlayeffect.apply())                     {                         var result = this.messagedialog.showdialog(                             new messagedialogargs(resources.resources.confirmclosingapplicationtitle,                                                   resources.resources.confirmclosingapplicationmessage,                                                   messageboxbutton.yesno,                                                   messageboximage.systemquestion));                          if (result == messageboxresult.yes)                         {                             return true;                         }                          return false;                     }                 }             }         }          return true;     }  private readonly ienumerable<iclosingvalidator> closingvalidatorclients;     private readonly mainwindow mainwindow;     private readonly imessagedialog messagedialog;     private readonly ioverlayeffect overlayeffect; 

update made work, suggestion export viewmodel typeof(iclosingvalidator) right, had add second export, not replace default one, didn't know have 2 of them. 2 exportattributes works!

i think implementation of iclosingvalidator @ wrong place. have similar project , following:

i have interface iclosingvalidator:

public interface iconfirmshellclosing {     /// <summary>     /// gets value indicates whether shell window can closed.     /// </summary>     bool canshellclose { get; } } 

this interface implemented viewmodels should asked, if shell can closed. in case viewmodels process can running should implement interface. each viewmodel implement canshellclose property , decide if process running in context. if viewmodels return true this, window can closed.

then, in instance of window, can subscribe windowclosing event , ask registered viewmodels, if window can closed. implementation goes viewmodel of window (or code behind file):

[importmany(typeof(lazy<iconfirmshellclosing>))] private ienumerable<lazy<iconfirmshellclosing>> _confirmshellclosingclients;      private void executewindowclosing(canceleventargs args)         {             if (_confirmshellclosingclients != null)             {                 foreach (var client in _confirmshellclosingclients)                 {                     if (!client.value.canshellclose)                     {                         // show dialog here , handle answer                     }                 }             }         } 

i hope help.

edit:

okay, still have few mistakes in implementation of viewmodel , validator.

first of all, class closingvalidator not needed anymore. want give responsibility viewmodels, , not central validator class.

after that, need change viewmodel this:

    [export]     public class tocviewmodel : iclosingvalidator     {         [importingconstructor]         public tocviewmodel(measurementsequenceexecution measurementsequenceexecution)         {             this.measurementsequenceexecution = measurementsequenceexecution;         }              public boolean canapplicationclose         {             { return !this.measurementsequenceexecution.ismeasurementsequencerunning; }             set             {                 this.measurementsequenceexecution.ismeasurementsequencerunning = !value;             }         } 

what happening now? viewmodel implements iclosingvalidator interface, has implement canshellclose property. in property, can define logic, in viewmodel can decide if shell can closed or not. if ever add other viewmodel, can implement interface , has different logic closing.

in importing in application itself, classes implementing iclosingvalidator interface imported , asked, if porperty true or false.

edit 2:

i have 3 .dll (helpingproject, interfaceproject , viewmodelproject) 3 should in directory compositioncontainer searching. in case, built container this:

var catalog = new aggregatecatalog();         catalog.catalogs.add(new directorycatalog(@"c:\projects\helpingsolution\helpingwpfproject\bin\debug"));         var container = new compositioncontainer(catalog);         container.composeparts(this); 

so debug folder scanned find matching exports. recommend search code in codebase , have @ container looking exports. not have 1 folder, can plugin folder or different locations. can find pretty introduction here.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -