1
votes

I recently came across MVVMCROSS which I think is a very good idea to solve cross platform issues. So I was tempted to port over an application I was working on and my entire libraries to make them more portable. Now I am trying ti bind my viewmodels to the views and I am facing several issues and questions...

I have seen the examples of how navigation works and how to start the first view which works fine. However, for my application I cannot use this.. My main view consists of a menu bar at the top of the window from where views can be called. The main window contains this :

  <Grid Height="Auto" Width="Auto">
<Grid.RowDefinitions>
  <RowDefinition Height="30" />
  <RowDefinition Height="*" />
</Grid.RowDefinitions>
<Menu Name="MainMenu"
      Height="25"
      Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
      Grid.Row="0">
  <MenuItem Header="Tools" Width="Auto">
    <MenuItem Header="Solar estimator" HorizontalAlignment="Left" Width="Auto" Click="Menu_Click"/>
  </MenuItem>
</Menu>
<DockPanel Grid.Row="1" Name="DockPanel" Height="Auto" Width="Auto">

</DockPanel>

So what I wish to do is that whenever I call a new view from the menu, I'll attach it to the dockpanel.

The function Menu_Click has this code :

      EnergyNeedsEstimatorView estimatorView = new EnergyNeedsEstimatorView();
  double estimatorViewHeight = estimatorView.Height;
  double estimatorViewWidth = estimatorView.Width;
  estimatorView.SetValue(UserControl.WidthProperty, double.NaN);
  estimatorView.SetValue(UserControl.HeightProperty, double.NaN);
  DockPanel.Children.Add(estimatorView);
  DockPanel.Height = estimatorView.Height;
  DockPanel.Width = estimatorView.Width;
  this.Height = estimatorViewHeight + MainMenu.Height + SystemParameters.WindowCaptionHeight + SystemParameters.ResizeFrameHorizontalBorderHeight;
  this.Width = estimatorViewWidth + SystemParameters.ResizeFrameVerticalBorderWidth + 10;

So view is displayed fine however, since I explicitly removed the IMvxAppStart part from my core library and removed the IMvxAppStart Resolve from DoSetup in my Desktop library, the link between the viewmodel and the view is no longer made. I suppose I could do like before and specify to my view that it's DataContext is the viewmodel and it would work like I did before using MVVMCross but I feel this is not the best approach.

So you probably are wondering, why not just add the menu bar to every view instead of trying to attach my views to a dockpanel? Well, I do not want to change my menu bars everywhere when I need to make a change. So I am trying to have a generic main window from where to display all views. Right now I am stuck and trying to figure out how I can do this with MVVMCross..

Any ideas?

1
Turns out it works fine if I manually associate the model to the view's DataContext. No surprises there, this is how I did it with my own MVVM framework. So now, the question remains... Anyone has any idea how you could have a MAINVIEW from where you attach views to be displayed depending on what option you access in a menu and having it so that MVVMCROSS binds the view and model without having to manually bind them through DataContext?tessierpat
Adding wpf and mvvm tags to this will help you get really good answers.Stuart

1 Answers

2
votes

If you ask the container to create you a View, then it automatically tries to Load a ViewModel for you - see the code in https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Wpf/Views/MvxWpfViewsContainer.cs

So you could replace your new with a call to

 car view = Mvx.Resolve<IMvxWpfViewsContainer>().CreateView(MvxViewModelRequest<MyViewModel>.GetDefaultRequest()):

However, normally in mvvmcross ViewModels and Applications don't talk directly to the Container - instead, they talk to a Presenter and it may be better to modify your code to use a presenter instead. Within this flow your menu would - send the Presenter ViewModelRequest objects - the Presenter then asks the Container for a View - the Container loads the View and provides it with info on it's ViewModel (how this is done depends on the platform and on the View). - the Presenter can then actually show the View on the display (normally a window) somehow.

In other frameworks, you may hear the term navigation service used instead of what Mvx calls Presenter