Reputation: 11
i have a model in my xamarin forms app that is used to generate a dynamic navigation menu
public class NavigationMenuItem
{
public string MenuText { get; set; }
public string MenuIcon { get; set; }
public Type TargetType { get; set; }
}
NavigationMenuItems.Add(new NavigationMenuItem
{
MenuText = "Settings",
MenuIcon = "settings.png"
TargetType = typeof(SettingsViewModel)
});
i have some code that allows me to navigate to a page via the page's view model so that a view model never references a page directly but via its view model. this works when i hard code the view model :
await _navigator.PushAsync<PageViewModel>();
but if i try
var vm = selectedItem.TargetType;
await _navigator.PushAsync<vm>();
i get an error "vm is a variable but is used like a type"
how can i pass the type held in TargetType
into PushAsync
thanks in advance
jas
Upvotes: 1
Views: 1438
Reputation: 43946
You can't pass an instance of Type
as a generic type argument to that method. But you could use reflection to achieve that:
var vm = selectedItem.TargetType;
MethodInfo mi = _navigator.GetType().GetMethod("PushAsync`1");
MethodInfo genericMethod = mi.MakeGenericMethod(vm);
await (Task)genericMethod.Invoke(_navigator);
So you retrieve the MethodInfo
for the generic method definition and create a specific MethodInfo
by providing the type to MakeGenericMethod
.
Finally you can invoke that method and cast the returned object into a Task
that you can await.
Upvotes: 0
Reputation: 137188
PushAsync
is expecting a type at compile time to tell it which method it needs to call.
If you don't know until runtime then you either need to pass the view model as an argument:
await _navigator.PushAsync(vm);
or implement the navigation on the view model:
await vm.PushAsync();
Upvotes: 1