Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin: Open page from string

I'm just starting to learn programming with Xamarin and C# and I really struggle with this question.

I have a master detail app. In my master page I would like to easily add buttons that link to a detail page. To do that I would like to make a method that I can call to with two parameters: Button text and the detail page linked to the button.

so basicly:

public class MainLink : Button
    {
        public MainLink(string name,string page)
        {
            Text = name;
            Command = new Command(o => {
                App.MasterDetailPage.Detail = new NavigationPage(new page);
                App.MasterDetailPage.IsPresented = false;
            });
        }
    }

This is what I have so far. But the line:

App.MasterDetailPage.Detail = new NavigationPage(new page);

ofcourse doesn't work.

How can I convert a string to a page type when I know the page's name already?

like image 456
Calvin Bootsman Avatar asked Jul 09 '26 03:07

Calvin Bootsman


2 Answers

You can also use the awsome Activator.CreateInstance() which takes in a Type which would be your page.

In order to get from a string to a Type you could do one of two things. Either try to get the type using the string alone (which I have not actually tried in Xamarin Forms) like so:

Type somethingPageType = Type.GetType("SomethingPage");

Or you could just pass the page Type into your Button's constructor and use that like so:

....
public MainLink(string name,string page, Type pageType) {
    ....
}

So to put it all together, either:

public class MainLink : Button
{
    public MainLink(string name,string page)
    {
        Text = name;
        Command = new Command(o => {
            Type pageType = Type.GetType(page);

            App.MasterDetailPage.Detail = new NavigationPage(Activator.CreateInstance(pageType) as Page);
            App.MasterDetailPage.IsPresented = false;
        });
    }
}

Or:

public class MainLink : Button
{
    public MainLink(string name, Type pageType)
    {
        Text = name;
        Command = new Command(o => {
            App.MasterDetailPage.Detail = new NavigationPage(Activator.CreateInstance(pageType) as Page);
            App.MasterDetailPage.IsPresented = false;
        });
    }
}

Two things to keep in mind though. First would be that if your page takes parameters into the page's constructor, you will need to use an overload of Activator.CreateInstance() to make that work.

Also, if you use the Xamarin Linker to remove unused stuff, it will probably mess this method up so you need to specifically tell the linker to leave your reflection code alone, for iOS and for Android

We do not link all code, only SDK Assemblies so we do not need to worry about the linker issue but it looks like you can use the following code on iOS to fix it (though I have not actually tested the code below):

Create a .cs file in your iOS project named whatever (LinkerIncludes.cs for example) and add the following code:

public class LinkerIncludes {
    public void Include() {
        var x = new System.ComponentModel.ReferenceConverter (typeof(void));
    }
}
like image 77
hvaughan3 Avatar answered Jul 11 '26 17:07

hvaughan3


NavigationPage gets an instance of a page. You can use a switch statement to initialize a new page, according to the page string:

switch (page)
{
    case "page1":
        App.MasterDetailPage.Detail = new NavigationPage(new Page1);
        break;
    case "page2":
        App.MasterDetailPage.Detail = new NavigationPage(new Page2);
        break;
    default:
        App.MasterDetailPage.Detail = new NavigationPage(new DefaultPage);
        break;            
}   
like image 27
Avi K. Avatar answered Jul 11 '26 17:07

Avi K.