0

I have three projects - "Bootstrapper", "ApplicationView" and "Presentation".

  • A project "Bootstrapper" has app.xaml.cs file which runs a MainWindow
  • A project "ApplicationView" has just necessary Windows - MainWindows.xaml, PersonWindow.xaml, SchoolWindows.xaml.
  • A project "Presentation" has ViewModels classes and Interfaces

In my viewmodel I want to revoke a window. But where I should create a object of a window? I've read an article that I should create all instances of classes in App.xaml.cs file. But how to call this object at App.xaml.cs from viewModel? I cannot create objects in a ViewModel classes as I cannot add a reference of "BootStrapper" to "Presentation" because VS 2010 throws an error - "Adding this project as a reference would cause a circular dependency".

App.xaml.cs of "Bootstrapper" project:

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        ComposeObjects();
        Application.Current.MainWindow.Title = "Loose Coupling - People Viewer";
        Application.Current.MainWindow.Show();
    }

    private static void ComposeObjects()
    {
        //MainWindow
        var repository = new ServiceRepository();            
        var viewModel = new PeopleViewerViewModel(repository);
        Application.Current.MainWindow = new MainWindow(viewModel);
        //SuperWindow
        var salut = new ServiceSalutation();
        var salutViewModel = new SuperWindowViewModel(salut);
        var NewForm = new SuperWindow(salutViewModel);
    }

MainWindowViewModel.cs of "Presentation" project:

    void NewForm(object parameter)
    {
        //New Window
        /*/var salut = new ServiceSalutation();
        //var salutViewModel = new SuperWindowViewModel(salut);*/
        //var NewForm = new SuperWindow();
        How can I revoke a SuperWindow.xaml from a project "ApplicationView"?
    }

How to call a SuperWindow.xaml of "Presentation" project from MainWindowViewModel.cs of Presentation project? I cannot add a reference of "BootStrapper" to "Presentation" because VS 2010 throws an error - "Adding this project as a reference would cause a circular dependency".

StepUp
  • 36,391
  • 15
  • 88
  • 148
  • This looks nasty. I would refactor the code and adopt an MVVM framework like Claiburn.Micro et al. You could set up a view to view model manager your self, but there is no real point in this unless you are learning MVVM from scratch... – MoonKnight Mar 21 '14 at 10:49
  • @Killercam, yeah, I am learning a louse coupling from scratch, but I do not have problems with creation new windows in simple MVVM. Moreover, this code is an example of loose coupling by plyralsight team. – StepUp Mar 21 '14 at 10:54
  • It is hard for me to advise here as this is likely to be a non-trivial solution... – MoonKnight Mar 21 '14 at 10:58
  • I rolled my own MVVM framework once, and the way I handled this was to have a service, where viewmodels were registered with associated views (windows), and viewmodels could have a dependency on this service (it was a singleton). Then, a viewmodel, or your bootstrapper, can "ask" the service to create a view for a viewmodel that it's given, and the service instantiates and shows the window, and sets the `DataContext`. – Steve Mar 21 '14 at 12:29

1 Answers1

1

I dont really completely understand our issue, but I assume you are trying to construct and then popup a windows from your viewmodel. This might be an answer. In your ViewModel put an action or func delegate to perform the external actions you require. you could pass it into your viewmodel's constructor perhaps like this.

Action newFormAction = () => {
       var salut = new ServiceSalutation();
       var salutViewModel = new SuperWindowViewModel(salut);
       var newForm = new SuperWindow(salutViewModel);
       newForm.Show();
   };

var viewModel = new PeopleViewerViewModel(repository, newFormAction);

then in your viewmodel you can invoke the action to create the popup, without needing a reference to the presentation layer

Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • Which would be a violation of MVVM, since your ViewModel depends on a concrete implementation of a view... which is exact what MVVM is meant to avoid. The correct way of handling windows/Views is via a Dependency Injection (bind a View to ViewModel in your bootstrapper, this way you don't pollute your ViewModel with dependencies. Or use a ViewLocator/Service or for more complex stuff NavigationService – Tseng Mar 21 '14 at 12:43
  • Its not a violation of MVVM to pass action or func delegates. – Dean Chalk Mar 21 '14 at 12:44
  • @DeanChalk , but I cannot add a reference for SuperWindow.xaml so my ViewModel classes cannot see any "Windows.xaml" files. – StepUp Mar 21 '14 at 12:51
  • if you want to popup a view from your viewmodel, this is the best way to do it without violating MVVM. If you want to interact with your view via the viewmodel, then bind the view beforehand with the same viewmodel – Dean Chalk Mar 21 '14 at 12:53
  • maybe you know some good examples of loosely coupled applications where a window revoke another window? some links will be very useful. – StepUp Mar 21 '14 at 13:01
  • @DeanChalk where I should write a code to bend a view ? Ins view model? – StepUp Mar 21 '14 at 22:51