2

I have an application like the one below (i know the colors are awful, I just made it this way to make it easier to explain):

It has 3 views and 3 viewmodels. A mainview(the gray one) which contains a content control which will change the view depending on which button is clicked, the homeview(the green one) which lets the user pick a file, and the blue one which is supposed to read out the contets of the file

MainView with HomeView: MainView with HomeView

MainView with FileView

MainView with FileView

The button for selecting the file is implemented in the codebehind of the homeview, it's just a simple openfiledialog, what I need is to pass the result of the openfiledialog from the homeview's (green one) code behind to the file's view (the blue one) or maybe to the FileViewModel (not sure which one is more appropriate here) so that it can show the contents of the file in the blue view. What I was trying to do was to call a command to try to communicate between these two views and pass the file path between them but i'm not sure if this is the appropriate approach.

sanya
  • 111
  • 11
  • 2
    Communication between views is always accomplished via the view model classes. The easiest solution is to move the shared data to the parent view model e.g. MainViewModel. For example add a FilePath property to the MainViewModel and let both views bind to it. – BionicCode Apr 11 '22 at 12:49
  • 1
    Second solution: when the MainViewModel is the navigation controller, simply assign the data (file path) to the next screen's view model, before selecting the next view. Difficult to give you a precise solution as it is not clear how your navigation works. But I guess the second solution should work for you. – BionicCode Apr 11 '22 at 12:52
  • 1
    Hi sanya. As @BionicCode points out, communication should be between the view models. I think it would be equally valid to have a `FilePath` property on HomeViewModel which the MainViewModel can read and pass to the FileViewModel. – Dan Stevens Apr 11 '22 at 12:53
  • 1
    You can follow [this example](https://stackoverflow.com/a/61323201/3141792) to create a nice and simple MVVM compliant view navigation. Then apply the proposed second solution to transfer the data between the view model classes – BionicCode Apr 11 '22 at 12:56
  • 1
    A third solution would be to add a FilePath dependency property to the MainWindow. Then let the code-behind of the green screen bind its own FilePath property to this MainWindow.FilePath property. Now when the code-behind of the green screen retrieves the file dialog result it sets its own FilePath property, which is then send to the MainWIndow.FilePath via data binding. Then let the blue screen's view model bind to the MainWIndow.FilePath property to obtain the file path for further file handling (which should ideally be part of the model). – BionicCode Apr 11 '22 at 13:01
  • 1
    But I recommend the second solution. Another solution I would give some consideration would be to share the same view model class between both views: they can bind both to the same instance as they obviously share the same data context. This eliminates any communication. This would be the most elegant solution if appropriate. – BionicCode Apr 11 '22 at 13:03

1 Answers1

1

You could use an event aggregator or a messenger to send an "event" or "message" from one component in your application to another one in a loosely coupled way.

Another similar option is to inject your view models (or other components) with a shared service and communicate between them using this one.

The third option is to use direct references, i.e. your HomeViewModel has a reference to the FileViewModel or vice versa. Note that this creates a tight coupling between your types which is usually something that you want to avoid for maintainability reasons.

You may also consider binding two views to the same view model.

mm8
  • 163,881
  • 10
  • 57
  • 88