Reputation: 8435
In order to create navigation service in Xamarin using MVVM, in following code GetPage
function, I am trying to create page object dynamically in Xamarin
after that I am creating model view of that page and assigning a newly created model view to page's binding context.
private static Page GetPage(Type viewModelType)
{
try
{
var pageType = viewModelType.Name.Replace("ViewModel", "Page");
Page page = (Page)Activator.CreateInstance(Type.GetType($"SEMA.View.{pageType}"));
page.BindingContext = Activator.CreateInstance(viewModelType);
if (page.BindingContext == null)
{
Debug.WriteLine("Binding Context is null");
}
return page;
}
catch (Exception e)
{
Debug.WriteLine(e.StackTrace);
}
return null;
}
but the issue with this code is I have parameter in my model view see below.
MainViewModel(MenuViewModel menuViewModel)
hence app is throwing error
Default constructor not found for type SEMA.ViewModel.MainViewModel
If I write default constructor then my parameter constructor i.e. MainViewModel(MenuViewModel menuViewModel)
won't get called.
public class MainViewModel : ViewModelBase
{
private MenuViewModel _menuViewModel;
public MainViewModel(MenuViewModel menuViewModel)
{
_menuViewModel = menuViewModel;
}
public MenuViewModel MenuViewModel
{
get
{
return _menuViewModel;
}
set
{
_menuViewModel = value;
OnPropertyChanged();
}
}
}
xaml file of main page
<?xml version="1.0" encoding="UTF-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:SEMA="clr-namespace:SEMA;assembly=SEMA"
xmlns:pages="clr-namespace:SEMA.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SEMA.View.MainPage" >
<MasterDetailPage.Master>
<pages:MenuPage BindingContext="{Binding MenuViewModel}" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<ContentPage BackgroundColor="Transparent" />
</MasterDetailPage.Detail>
</MasterDetailPage>
I am trying to create app based on the xamarin sample provided by xamarin community where in they have used autofac
and they are using following code to create page and map it with view model, but I dont want to use autofac hence I am creating view model using Activator page.BindingContext = Activator.CreateInstance(viewModelType);
and not using ViewModelBase viewModel = Locator.Instance.Resolve(viewModelType) as ViewModelBase;
page.BindingContext = viewModel;
protected Page CreateAndBindPage(Type viewModelType, object parameter)
{
Type pageType = GetPageTypeForViewModel(viewModelType);
if (pageType == null)
{
throw new Exception($"Mapping type for {viewModelType} is not a page");
}
Page page = Activator.CreateInstance(pageType) as Page;
ViewModelBase viewModel = Locator.Instance.Resolve(viewModelType) as ViewModelBase;
page.BindingContext = viewModel;
return page;
}
Upvotes: 1
Views: 817
Reputation: 1583
Activator.CreateInstance
has an overload that accepts an array of objects as parameters for the constructor.
private static Page GetPage(Type viewModelType, MenuViewModel menuViewModel)
{
//...
page.BindingContext = Activator.CreateInstance(viewModelType, new object[] { menuViewModel });
//...
}
Upvotes: 1