Reinitializing MasterPage is throwing null exception in IOS - Xamarin forms

Viewed 364

I have a MDPage which is a MasterDetailPage which calls side menu items list page as Master. The Detail for this is added with a new NavigationPage of a home page.

My code is

public MDPage(){
Master = new SideMenuPage();
InitializeComponent();
masterPage.ListView.ItemSelected += OnItemSelected;

Detail = new NavigationPage(new HomePage())
{
    BarBackgroundColor = Color.Black,
    BarTextColor = Color.White,
};}

I have a requirement where the NavigationPage contains a bottom menu such that on clicking a bottom menu, the MDPage needs to be reinitialized to set a new NavigationPage of a different page (say AboutUs page). So i added a parameterized constructor for MDPage and on clicking the bottom menu item i am calling App.Current.MainPage = new MDPage("AboutUs").Below is the parameterized constructor.

  public MDPage(string bottomMenuItem)
 {
Master = new SideMenuPage();
InitializeComponent();
masterPage.ListView.ItemSelected += OnItemSelected;

if("AboutUs" == bottomMenuItem)
{
   Detail = new NavigationPage(new AboutUs())
   {
      BarBackgroundColor = Color.Black,
      BarTextColor = Color.White,
   };
}}

Here the MDPage constructor is called initially when i open the app. Then from the side menu i have the option to open a HomePage which is added as Detail. Note that this HomePage contains a bottom sub menu, which is nothing but an image. On tapping this, it should again reinitialize the MDPage. Here this is working fine in Andorid. But in iOS, it is throwing null exception. It is not allowing me to set Master = new SideMenuPage(); I have found the root cause by trial and error as this code will not throw exception and it is throwing in the iOS Main.cs file. Please help me.

MainPage - XAML

<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                  xmlns:local="clr-namespace:ClubApp.Views;assembly=ClubApp"
             x:Class="ClubApp.Views.MainPage">

  <MasterDetailPage.Master>
    <local:MasterPage x:Name="masterPage" />
  </MasterDetailPage.Master>
  <MasterDetailPage.Detail>
    <NavigationPage>
      <x:Arguments>

      </x:Arguments>
    </NavigationPage>
  </MasterDetailPage.Detail>
</MasterDetailPage>

MainPage.xaml.cs

using System.Linq;using System.Text;using System.Threading.Tasks;using Xamarin.Forms;namespace Test.Views{
public partial class MainPage : MasterDetailPage
{
    public MainPage()
    {

        Master = new MasterPage();
        InitializeComponent();
        masterPage.ListView.ItemSelected += OnItemSelected;

        Detail = new NavigationPage(new Views.HomePage())
        {
            BarBackgroundColor = Color.Black,
            BarTextColor = Color.White,
        };
    }

    public MainPage(string bottomMenu)
    {

        Master = new MasterPage();
        InitializeComponent();
        masterPage.ListView.ItemSelected += OnItemSelected;

        if ("News" == bottomMenu)
        {
            Detail = new NavigationPage(new Views.HomePage())
            {
                BarBackgroundColor = Color.Black,
                BarTextColor = Color.White,
            };
        }
        else if ("Profile" == bottomMenu)
        {

            Detail = new NavigationPage(new Views.Profile())
            {
                BarBackgroundColor = Color.Black,
                BarTextColor = Color.White,
            };
        }
    }

    async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        try
        {
            var item = e.SelectedItem as MasterPageItem;
            if (item != null)
            {
                if (item.Title == "News")
                {
                    Detail = new NavigationPage(new Views.NewsPage())
                    {
                        BarBackgroundColor = Color.Black,
                        BarTextColor = Color.White,
                    };
                }

                if (item.Title == "Home")
                {

                    Detail = new NavigationPage(new Views.HomePage())
                    {
                        BarBackgroundColor = Color.Black,
                        BarTextColor = Color.White,
                    };
                }
                if (item.Title == "Profile")
                {

                    Detail = new NavigationPage(new Views.Profile())
                    {
                        BarBackgroundColor = Color.Black,
                        BarTextColor = Color.White,
                    };
                }

                masterPage.ListView.SelectedItem = null;
                IsPresented = false;
            }
        }
        catch (Exception ex)
        {

        }

    }
}}

MasterPage.xaml

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             x:Class="Test.Views.MasterPage">  <ContentPage.Content>
<StackLayout   VerticalOptions="FillAndExpand" BackgroundColor="#10000c" Padding = "0,50,0,0" >
  <StackLayout  x:Name="slUserProfile" Orientation="Vertical" Spacing = "0" 
                VerticalOptions="FillAndExpand">
    <Image Source="{Binding member_image}" x:Name="imgSideImage"
             HorizontalOptions="CenterAndExpand" Aspect="AspectFill" HeightRequest="100" 
             WidthRequest="100" />

    <Label Text="{Binding name}" TextColor="#efa747" 
                          FontSize ="17"
                          HorizontalOptions="CenterAndExpand"/>
  </StackLayout >

  <ListView x:Name="lvSideMenu" VerticalOptions="FillAndExpand" SeparatorVisibility="None" 
            BackgroundColor="Black">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <StackLayout Padding="15,5,0,0" Orientation="Horizontal">
            <Image Source="{Binding IconSource}"/>
            <StackLayout Padding = "10,0,0,0">
              <local:CustomLabel Text="{Binding Title}" VerticalOptions="CenterAndExpand"
                   TextColor="#dac6ac" FontSize ="14"/>
            </StackLayout>
          </StackLayout>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</StackLayout></ContentPage.Content></ContentPage>

MasterPage.xaml.cs

using Xamarin.Forms;namespace Test.Views{
public partial class MasterPage : ContentPage
{
    public ListView ListView { get { return lvSideMenu; } }
    public Page Detail { get; set; }
    public MasterPage()
    {
        InitializeComponent();
        var masterPageItems = new List<MasterPageItem>();  
        //Fills side menu items.
        masterPageItems.Add(new MasterPageItem
        {
            Title = "Profile",
            IconSource = "profile_sidemenu.png"
        });
        masterPageItems.Add(new MasterPageItem
        {
            Title = "Home",
            IconSource = "home_smenu.png"
        });
        masterPageItems.Add(new MasterPageItem
        {
            Title = "News",
            IconSource = "news_smenu.png"
        });
        lvSideMenu.ItemsSource = masterPageItems;
        Icon = "menu.png";
        Title = "Menu";   
    }
}
public class MenuItems
{
    public string MenuTitle { get; set; }
}
public class MasterPageItem
{
    public string Title { get; set; }
    public string IconSource { get; set; }
}}

HomePage.xaml

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"           x:Class="Test.Views.HomePage" Title="Home"><ContentPage.Content><StackLayout>   <Label Text="This is Home page"/></StackLayout></ContentPage.Content></ContentPage>

Profile.xaml

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Test.Views.Profile" Title="Profile"><ContentPage.Content>   <StackLayout>
    <StackLayout>
      <Label Text="This is Profile page" />
    </StackLayout>
    <StackLayout HeightRequest="80">
      <Grid RowSpacing="0" ColumnSpacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <StackLayout x:Name="tProfile" BackgroundColor="Red" Grid.Column="0" Spacing="0" Padding="0,10,0,10">
          <Image Source="bprofileSel.png" HorizontalOptions="Center" VerticalOptions="End"/>
          <Label Text="Profile" FontSize="10" TextColor="White" HorizontalOptions="CenterAndExpand" VerticalTextAlignment="Center"/>
        </StackLayout>
        <StackLayout x:Name="tNews" BackgroundColor="Black" Grid.Column="1" Spacing="0" Padding="0,10,0,10">
          <Image Source="bNewsUnsel.png" HorizontalOptions="Center" VerticalOptions="End"/>
          <local:CustomLabel Text="News" FontSize="10" TextColor="White" HorizontalOptions="CenterAndExpand" VerticalTextAlignment="Center"/>
        </StackLayout>
      </Grid>
    </StackLayout>
 </StackLayout></ContentPage.Content></ContentPage>

Profile.xaml.cs

Using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Xamarin.Forms;namespace Test.Views{
public partial class Profile : ContentPage
{

    public Profile()
    {

        InitializeComponent();
        try
        {
            tProfile.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(() => ProfileClicked()),
            });

            tNews.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(() => NewsClicked()),
            });
        }
        catch (Exception ex)
        {
        }
    }

    private void ProfileClicked()
    {
        App.Current.MainPage = new MainPage("Profile");
    }

    private void NewsClicked()
    {
        App.Current.MainPage = new MainPage("News");
    }
}}

News page can be set similar to the profile page. In app.cs call MainPage = new MainPage()

Here when the app is launched, it will show the HomePage with the side menu. Now when i click a menu (say profile from side menu), it will take me to the profile page and according to the design a bottom submenus can be seen there. Clicking on it will cause the null exception occurring in iOS code. This is working fine in android. My assumption is the root cause is due to MasterPage reinitialization to Master. But i need this requirement to be flown like this. Please help me.

This is the error in iOS Main.cs iOS Error

0 Answers
Related