Thursday, October 4, 2018

MasterDetailPage: Accepting something other than a Page

Leave a Comment

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?

1 Answers

Answers 1

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).

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment