I´ve got 2 ViewModels (ConfigurationViewModel and EditConfigurationViewModel). In the ConfigurationViewModel I’ve got the following code:
public ConfigurationViewModel()
{
NewConfigCommand = new MvxRelayCommand(DoNewConfig);
EditConfigCommand = new MvxRelayCommand<ConfigurationSet>(DoEditConfig);
}
private void DoNewConfig()
{
this.RequestNavigate<EditConfigurationViewModel>();
}
private void DoEditConfig(ConfigurationSet config)
{
this.RequestNavigate<EditConfigurationViewModel>(new { id = config.Id.ToString() });
}
In the EditConfigurationViewModel I’ve got the following code:
public EditConfigurationViewModel()
{
Configuration = new ConfigurationSet();
}
public EditConfigurationViewModel(string id)
{
Configuration = ConfigDataStore.GetConfiguration(Guid.Parse(id));
}
What I want to achieve is something very simple… In the ConfigurationViewModel when the NewConfigCommand is fired, I want to navigate to the EditConfigurationViewModel, and use the parameterless constructor. When the EditConfigCommand is fired I want to use the constructor that receives a string.
The problem with this code is that no matter what command is fired, the parameterless constructor is allways used and the code never reaches the other constructor.
I did some experiments, by removing the parameterless constructor, and the result was that the other constructor is called and I get the expected result for the EditConfigurationCommand, but if I try to fire the NewConfigurationCommand an exception is throw due too the inesxistence of a parameterless constructor (so far so good).
Unfortunately, at this moment I don’t have VS2010 installed, so I’m not able to debug through PCL code… I’ve done some “eye debug” and found this class MvxViewModelLocator. I think the problem is somewhere here. Maybe in the DoLoad method when it tries to get the MethodInfo…
At this point I just wanted to know if I’m doing something wrong or if this is the expected result. Meanwhile I think I’ll take a chance on installing VS2010 and pray that it won´t break anything…
On the PCL debugging issue, why not just add a Win8 or WP7/8 UI – then you can debug through the PCL code…
On the main question – about how to use multiple constructors… I’d suggest you don’t.
For me, edit and new are two different views and two different viewmodels – they may share common properties and common layout – but this can be achieved using inheritance, using UserControls, using
includeaxml, etc.For an example of what I generally use for new and edit see https://github.com/slodge/MvvmCross/tree/vnext/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement/ViewModels
If you do insist on carry on using one viewmodel, then you could consider using a ‘magic value’ for New – e.g. if Guid.Empty is passed then that means new?
Alternatively, you could just drop your parameterless constructor and could add a default value to the second one:
I think that would work?
Finally, if none of that seems suitable to you, then you could consider overriding the ViewModel construction mechanism.
To help with this, there’s a fairly detailed recent post on how to write your own default ViewModelLocator for MvvmCross – see http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-more.html
Using this approach, you could create a much more custom navigation model – or if this is the only special view model, then I suspect you could create a default viewModelLocator like:
and register that locator in App.cs using: