Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShowMenuAction targeting null #40

Open
kcox40 opened this issue Jul 7, 2017 · 6 comments
Open

ShowMenuAction targeting null #40

kcox40 opened this issue Jul 7, 2017 · 6 comments

Comments

@kcox40
Copy link

kcox40 commented Jul 7, 2017

I created a Control Template in my PCL App.xaml and App.xaml.cs to create a custom header for my application. I was just messing around to see if I could add a universal slide menu by having App.xaml.cs implement IMenuContainerPage. I set it all up, but the ShowMenuAction?.Invoke() targets null when I use it in the App class. Is this because its not actually a Page? or is there a way I could actually invoke the ShowMenuAction and HideMenuAction directly from the App class?

`using System;
using Xamarin.Forms;
using static EngApp.MainActivityPage;
using SlideOverKit;

namespace EngApp
{
public partial class App : Application, IMenuContainerPage
{

    public Action HideMenuAction
    {
        get;
        set;
    }

    public Action ShowMenuAction
    {
        get;
        set;
    }

    public SlideMenuView SlideMenu
    {
        get;
        set;
    }
    public SlideRightFilterView filterMenu;
    public NavigationPage NavPage { get; private set; }
    public App()
    {

        InitializeComponent();
        MainPage = new DeviceFinder();
        this.SlideMenu = new SlideRightFilterView();

    }

    protected override void OnStart()
    {
        // Handle when your app starts
    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
    void OpenFilter(object sender, EventArgs args)
    {
        if (this.SlideMenu.IsShown)
        {
            HideMenuAction?.Invoke();
        }
        else
        {
            ShowMenuAction?.Invoke();

        }
    }
}

}`

XAML CONTROL TEMPLATE

`

<Application.Resources >

	<!-- Application resource dictionary -->
    <ResourceDictionary >
        <ControlTemplate x:Key="MainPageTemplate" >
            <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" ColumnSpacing="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=".3*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="1.5*"/>
                    <ColumnDefinition Width=".4*"/>
                    <ColumnDefinition Width=".4*"/>
                 
                </Grid.ColumnDefinitions>
                <Image x:Name="arrow" Source="arrow.png" Aspect="AspectFit" BackgroundColor="Transparent" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="1" Margin="12,17,0,17" HorizontalOptions="StartAndExpand">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OpenMenu"/>
                    </Image.GestureRecognizers>
                </Image>
                <Image Source="eaton_corporation_logo.png" Aspect="AspectFit" BackgroundColor="Transparent" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="1" HorizontalOptions="StartAndExpand">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OpenMenu"/>
                    </Image.GestureRecognizers>
                </Image>
                <StackLayout  Grid.Column="3" Grid.Row="0" Padding="10, 0, 10, 0" >

                    <Picker x:Name="ChannelPicker" SelectedIndexChanged="SelectedChannel" TextColor="DarkGray" SelectedIndex="0">
                        <Picker.Items>
                            <x:String>Channel 11</x:String>
                            <x:String>Channel 12</x:String>
                            <x:String>Channel 13</x:String>
                            <x:String>Channel 14</x:String>
                            <x:String>Channel 15</x:String>
                            <x:String>Channel 16</x:String>
                            <x:String>Channel 17</x:String>
                            <x:String>Channel 18</x:String>
                            <x:String>Channel 19</x:String>
                            <x:String>Channel 20</x:String>
                            <x:String>Channel 21</x:String>
                            <x:String>Channel 22</x:String>
                            <x:String>Channel 23</x:String>
                            <x:String>Channel 24</x:String>
                            <x:String>Channel 25</x:String>
                            <x:String>Cahnnel 26</x:String>
                        </Picker.Items>
                    </Picker>
                </StackLayout>
                <Image Source="freezedark.png" Grid.Column="4" Grid.Row="0" HorizontalOptions="EndAndExpand" Margin="0,10,4,10">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="Freeze"/>
                    </Image.GestureRecognizers>
                </Image>
                <Image Source="filter.png" Grid.Column="5" Grid.Row="0" HorizontalOptions="EndAndExpand" Margin="5,12,5,12">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OpenFilter"/>
                    </Image.GestureRecognizers>
                </Image>

                <ContentPresenter x:Name ="notToolBar" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Grid.Column="0"  Grid.Row="1" Grid.ColumnSpan="6"/>
            </Grid>
        </ControlTemplate>
    </ResourceDictionary>

</Application.Resources>

`

@jessejiang0214
Copy link
Contributor

Yes, the container must be a Page.
Why do you want to show popup in App class?

@kcox40
Copy link
Author

kcox40 commented Jul 12, 2017

I created a custom toolbar as a control template in the App class (it can be applied to any page and has custom images and controls ):

`

<Application.Resources >

	<!-- Application resource dictionary -->
    <ResourceDictionary >
        <ControlTemplate x:Key="MainPageTemplate" >
            <Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" ColumnSpacing="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=".3*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="1.5*"/>
                    <ColumnDefinition Width=".4*"/>
                    <ColumnDefinition Width=".4*"/>
                 
                </Grid.ColumnDefinitions>
                <Image x:Name="arrow" Source="arrow.png" Aspect="AspectFit" BackgroundColor="Transparent" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="1" Margin="12,17,0,17" HorizontalOptions="StartAndExpand">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OpenMenu"/>
                    </Image.GestureRecognizers>
                </Image>
                <Image Source="eaton_corporation_logo.png" Aspect="AspectFit" BackgroundColor="Transparent" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="1" HorizontalOptions="StartAndExpand">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OpenMenu"/>
                    </Image.GestureRecognizers>
                </Image>
                <StackLayout  Grid.Column="3" Grid.Row="0" Padding="10, 0, 10, 0" >

                    <Picker x:Name="ChannelPicker" SelectedIndexChanged="SelectedChannel" TextColor="DarkGray" SelectedIndex="0">
                        <Picker.Items>
                            <x:String>Channel 11</x:String>
                            <x:String>Channel 12</x:String>
                            <x:String>Channel 13</x:String>
                            <x:String>Channel 14</x:String>
                            <x:String>Channel 15</x:String>
                            <x:String>Channel 16</x:String>
                            <x:String>Channel 17</x:String>
                            <x:String>Channel 18</x:String>
                            <x:String>Channel 19</x:String>
                            <x:String>Channel 20</x:String>
                            <x:String>Channel 21</x:String>
                            <x:String>Channel 22</x:String>
                            <x:String>Channel 23</x:String>
                            <x:String>Channel 24</x:String>
                            <x:String>Channel 25</x:String>
                            <x:String>Cahnnel 26</x:String>
                        </Picker.Items>
                    </Picker>
                </StackLayout>
                <Image Source="freezedark.png" Grid.Column="4" Grid.Row="0" HorizontalOptions="EndAndExpand" Margin="0,10,4,10">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="Freeze"/>
                    </Image.GestureRecognizers>
                </Image>
                <Image Source="filter.png" Grid.Column="5" Grid.Row="0" HorizontalOptions="EndAndExpand" Margin="5,12,5,12">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="**OpenFilter**"/>
                    </Image.GestureRecognizers>
                </Image>

                <ContentPresenter x:Name ="notToolBar" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Grid.Column="0"  Grid.Row="1" Grid.ColumnSpan="6"/>
            </Grid>
        </ControlTemplate>
    </ResourceDictionary>

</Application.Resources>

`

And the "OpenFilter" tapped event (handled in App.aaml.cs) is what should open the filter side menu.

I can just use messaging center or an event to tell it to open the menu in whatever page is open in the "ContentPresenter" (the non toolbar area). But I already have another menu defined on that page using SlideOverKit. I was hoping this could be a universal workaround to the fact that slideOverKit only allows one menu per page. I've already managed to get two menus working (by using MasterDetailPage + SlideOverKit) but I need a third menu that slides out from the right. I thought that if this one was called from App.xaml/cs that it might be able to act as a third menu. Like I assumed it only works if the container is a Page...

I also posted my issue (worded differently) on the Xamarin forum: https://forums.xamarin.com/discussion/comment/285072#Comment_285072

If you have any suggestions to get the third menu please let me know.

@Finneyv
Copy link

Finneyv commented Dec 11, 2017

@jessejiang0214 Hey I know this issue is 6 months old but I've encountered this same issue with a MasterDetailPage that implements the IMenuContainerPage interface. Here's my code:

`

public class MasterDetailMenuPage : MasterDetailPage, IMenuContainerPage
{
public MasterDetailMenuPage() {
this.MasterBehavior = MasterBehavior.Split;
}

	public Action HideMenuAction { get; set; }

    public Action ShowMenuAction { get; set; }

	SlideMenuView slideMenu;
	public SlideMenuView SlideMenu
	{
		get
		{
			return slideMenu;
		}

		set
		{
			if (slideMenu != null)
				slideMenu.Parent = null;
			slideMenu = value;
			if (slideMenu != null)
				slideMenu.Parent = this;
		}
	}

	public void ShowMenu()
	{
        ShowMenuAction?.Invoke();
    }

	public void HideMenu()
	{
        HideMenuAction?.Invoke();
    }
}

`
Like with kcox40's issue the "ShowMenuAction?.Invoke();" always returns null for it's target.
The strange thing is that I only experience this on Android and it only started happening after I upgraded to Xamarin Forms 2.5.0.121934.

@Finneyv
Copy link

Finneyv commented Dec 11, 2017

OK I've figured what I was doing wrong. Instead of targeting the MasterDetailsPage itself I had to target the Master page. I was doing this on iOS but not on Android. Thank you for your time.

@shreyans-wakekar
Copy link

ShowMenuAction targeting null in ViewModel. Can anybody help ?
How to show hide menu in viewmodel..

@ojuniour
Copy link

ojuniour commented Sep 7, 2018

im getting same issue. @Finneyv solution is very clear. Can you elaborate on fix, please/ Thanks.

EDIT: stupid me. I figured it out. In the renderer (typeof() at the top) you have to edit and match the the calling page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants