Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MasterDetailPage: Accepting something other than a Page

I am following the tutorial here on Master-Detail Page

One question I am having:

Part of the solution calls for an item class as follows:

public class MasterPageItem
{
    public string Title { get; set; }
    public string IconSource { get; set; }
    public Type TargetType { get; set; }
}

And in the Xaml file, you call it as this:

   <ListView.ItemsSource>
        <x:Array Type="{x:Type local:MasterPageItem}">
            <local:MasterPageItem Title="Radio" IconSource="hamburger.png" TargetType="{x:Type local:RadioPage}" />

            <local:MasterPageItem Title="Item 1" TargetType="{x:Type temp:ContactsPage}" />
            <local:MasterPageItem Title="Item 2" TargetType="{x:Type temp:TodoListPage}" />
            <local:MasterPageItem Title="Item 3" TargetType="{x:Type temp:ReminderPage}" />
            <local:MasterPageItem Title="File 4"  TargetType="{}Foodaddy" />
        </x:Array>
    </ListView.ItemsSource>

What I want to do is for "File 4", rather than creating a view, I would rather send in a string, (or better an Enum), so I can call different functions. Example: Open a webpage, log out, etc. How do I modify TargetType?

like image 325
Paul Avatar asked May 28 '18 17:05

Paul


1 Answers

If you notice in this piece of code you will see that the OnItemSelected method is handling the event and expecting for a MasterPageItem:

void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
    var item = e.SelectedItem as MasterPageItem;
    if (item != null) {
        Detail = new NavigationPage ((Page)Activator.CreateInstance (item.TargetType));
        masterPage.ListView.SelectedItem = null;
        IsPresented = false;
    }
}

It is doing the navigation directly through the event handler (it's not the MVVM way to do that).

I guess @Jason's advice fits for you. Here's a way to achieve that:

You can create your own model to replace the MasterPageItem and handle its properties in a MasterDetailMenuViewModel, for example, and modify the handling to something more accurate for your need.

See the example below:

Create an amazing model to your menu items

public class AmazingMenuItem
{
    public string ItemName { get; set; }
    public string ItemIconSource { get; set; }
    public EnumAction ActionType { get; set; }
    public object ActionParameter { get; set; }
}

public enum EnumAction
{
    OpenPage = 0,
    ShowMessage = 1,
    PopToRoot = 2
    /* ... and so on  */
}

Handle it in the view model*

public class MenuViewModel : SomeINotifyPropertyChangedImplementation
{
    public Command ItemSelectedCommand { get; }
    /*
        Other properties
    */

    public MenuViewModel()
    {
        ItemSelectedCommand = new Command<AmazingMenuItem>(ExecuteItemSelected);
    }

    private void ExecuteItemSelected(AmazingMenuItem item)
    {
        if(item != null)
        {
            switch(item.ActionType)
            {
                case EnumAction.OpenPage:
                    var detail = (App.Current.MainPage as MasterDetailPage).Detail;

                    if(detail is NavigationPage)
                        detail.PushAsync((Page)Activator.CreateInstance(item.ActionParameter.GetType()));
                    else
                        (App.Current.MainPage as MasterDetailPage).Detail = new NavigationPage((Page)Activator.CreateInstance(item.ActionParameter.GetType()));

                    break;
                case EnumAction.ShowMessage:
                    App.Current.MainPage.DisplayAlert(item.ActionParameter.ToString(), "Ok", "Cancel");

                    break;
                case EnumAction.PopToRoot:
                    (App.Current.MainPage as MasterDetailPage)?.Detail.PopToRootAsync();

                    break;

            }
        }
    }
}

* - Supposing you have made the bindings correctly

It's not a complete implementation, but I hope you've figured out a general idea of it.

Let me know if I can help you to get thru this (and sorry for any English mistake, it's not a native here).

like image 141
Diego Rafael Souza Avatar answered Nov 16 '22 01:11

Diego Rafael Souza