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?
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:
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 */
}
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With