Question:
Tell me what is the right way to go.
The WPF form has a Browse button that should call OpenFileDialog
and, after selecting a file, pass its name to the textbox
.
Using the MVVM pattern, I should not change the textbox value, but change the corresponding value in the VM. And here's my question. Calling OpenFileDialog
should I make in VM as ICommand
, or from my form on which button?
Answer:
Dialogues are the cornerstone of MVVM because it is assumed that the VM does not know anything about the View, but must receive data from it. We get that, on the one hand, View should call VM commands with parameters and VM shouldn't work with display in any way. Those. dialogs are View. And on the other hand: View should not contain logic / code, and calling the dialog box and getting the result is no logic / code.
The simplest option: in the View code, hang an event handler on the event for which you should display the file selection dialog in which you create and display the dialog to the user, and upon successful closing of the event, call the VM command from the code (in this case, you can do with the interface method , without declaring a command).
The code on the VM side should receive a path string to the file (s) being opened and, possibly, the type of access (read / read-write, etc.)
PS: If you stick with MVVM when developing, IMHO, the main thing to always remember is that you must keep your VM unit testable with Unit tests. (i.e. if instead of M you slip test data, and instead of View directly call commands, all public methods and commands should be tested without dancing with a tambourine) Creating dialogs in the VM breaks this scheme.
A more complicated option: Sometimes it happens that a custom dialogue is needed. With a bunch of parameters that must be set at the VM level. And in general, it is possible that the viewer should control the dialog (i.e., for example, first display it, and then start moving it around the screen, and then something else) In this case, it is possible to use delegates that you define at the VM level. You define the input and output parameters in the same way in the VM. The assignment of the method to the delegate is carried out in the code that belongs to the View. It implements the display of the dialog (or whatever) and the logic of behavior / display control. In principle, you can pass anything to the output, starting from the result of the dialog and ending with an object that implements the interface you declared through which you control the window. This version of the code comes out slightly more compact than the version with interfaces. Testability is not affected.
PSS: IMHO, there is no "correct" option outside the global context of the task. Remember that "Hello World" written by all canons and standards is over 100 lines of code. Variants with interfaces / delegates, etc., dancing with a tambourine and a dozen accompanying classes are specific, difficult to understand, maintain and debug (!) And are only needed if you have more than 3 of these dialogs (of different types) and are expected in the future. they are all non-standard and with complex behavior. In general, "Don't complicate" (c)