WPF OpenFileDialog with the MVVM pattern? -
i started learning mvvm pattern wpf. hit wall: what do when need show openfiledialog?
here's example ui i'm trying use on:
when browse button clicked, openfiledialog should shown. when user selects file openfiledialog, file path should displayed in textbox.
how can mvvm?
update: how can mvvm , make unit test-able? solution below doesn't work unit testing.
what create interface application service performs function. in examples i'll assume using mvvm toolkit or similar thing (so can base viewmodel , relaycommand).
here's example of extremely simple interface doing basic io operations openfiledialog , openfile. i'm showing them both here don't think i'm suggesting create 1 interface 1 method around problem.
public interface ioservice { string openfiledialog(string defaultpath); //other similar untestable io operations stream openfile(string path); }
in application, provide default implementation of service. here how consume it.
public myviewmodel : viewmodel { private string _selectedpath; public string selectedpath { { return _selectedpath; } set { _selectedpath = value; onpropertychanged("selectedpath"); } } private relaycommand _opencommand; public relaycommand opencommand { //you know drill. ... } private ioservice _ioservice; public myviewmodel(ioservice ioservice) { _ioservice = ioservice; opencommand = new relaycommand(openfile); } private void openfile() { selectedpath = _ioservice.openfiledialog(@"c:\where\my\file\usually\is.txt"); if(selectedpath == null) { selectedpath = string.empty; } } }
so that's pretty simple. last part: testability. 1 should obvious, i'll show how make simple test this. use moq stubbing, can use whatever you'd of course.
[test] public void openfilecommand_userselectsinvalidpath_selectedpathsettoempty() { mock<ioservice> ioservicestub = new mock<ioservice>(); //we use null indicate invalid path in our implementation ioservicestub.setup(ioserv => ioserv.openfiledialog(it.isany<string>())) .returns(null); //setup target , test myviewmodel target = new myviewmodel(ioservicestub.object); target.opencommand.execute(); assert.isequal(string.empty, target.selectedpath); }
this work you.
there library out on codeplex called "systemwrapper" (http://systemwrapper.codeplex.com) might save having lot of kind of thing. looks filedialog not supported yet, you'll have write interface one.
hope helps.
edit:
i seem remember favoring typemock isolator faking framework. here's same test using isolator:
[test] [isolated] public void openfilecommand_userselectsinvalidpath_selectedpathsettoempty() { ioservice ioservicestub = isolate.fake.instance<ioservice>(); //setup stub arrangements isolate.whencalled(() => ioservicestub.openfiledialog("blah")) .wascalledwithanyarguments() .willreturn(null); //setup target , test myviewmodel target = new myviewmodel(ioservicestub); target.opencommand.execute(); assert.isequal(string.empty, target.selectedpath); }
hope helpful well.
Comments
Post a Comment