I am not sure how to properly bind a selected menu item from a listview to its associated load page event in the view model.
The way I have it right now it works. BUT, the problem is that a menu page stays selected(still highlighted orange when sliding menu from left) and if clicked again the side menu does not disappear and nothing happens, until selecting a different page. ( IPropertyChanged does not trigger if clicking same item...or does it trigger anyways and checks if there is a change and sets it or not?)
How to fix this please in the correct MVVM way?
The MasterDetailPage:
<?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:views="clr-namespace:MyApp.Views"
x:Class="MyApp.Views.MyMainPage"
Title="My Main Page">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<ContentPage.Content>
<Grid BackgroundColor="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="130" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Image Source="menu_background.png"
Aspect="AspectFill" />
<StackLayout Padding="0,20,0,0"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
<Image Source="ac_logo.png"
Aspect="AspectFit"
WidthRequest="60"
HeightRequest="60" />
<Label Text="myAC" TextColor="White" FontSize="Large" />
</StackLayout>
</Grid>
<StackLayout Grid.Row="1"
Spacing="15">
<ListView ItemsSource="{Binding MenuList}"
SelectedItem="{Binding MenuSelectedItem, Mode=TwoWay}"
RowHeight="45"
SeparatorVisibility="Default"
BackgroundColor="#e8e8e8">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<!-- Main design for our menu items -->
<StackLayout VerticalOptions="FillAndExpand"
Orientation="Horizontal"
Padding="20,10,0,10"
Spacing="20">
<Image Source="{Binding IconSource}"
WidthRequest="30"
HeightRequest="30"
VerticalOptions="Center" />
<Label Text="{Binding Title}"
FontSize="Medium"
VerticalOptions="Center"
TextColor="Black"/>
</StackLayout>
<BoxView HeightRequest="1" BackgroundColor="Gray"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Grid>
</ContentPage.Content>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<views:StudentHomePage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
My ViewModel:
public class MyMainPageVM : BaseVM
{
public ObservableCollection<MenuPageItem> MenuList { get; set; }
private MenuPageItem _menuSelectedItem = null;
public MenuPageItem MenuSelectedItem
{
get
{
return _menuSelectedItem;
}
set
{
//if (_menuSelectedItem != value)
// {
_menuSelectedItem = value;
// navigate
(App.Current.MainPage as MasterDetailPage).Detail = new NavigationPage((Page)Activator.CreateInstance(_menuSelectedItem.TargetType));
(App.Current.MainPage as MasterDetailPage).IsPresented = false;
//}
}
}
public MyMainPageVM()
{
MenuList = new ObservableCollection<MenuPageItem>();
populateMenuList();
}
private void populateMenuList()
{
MenuList.Add(new MenuPageItem() { Title = "Home", IconSource = "home.png", TargetType = typeof(MyHomePage) });
MenuList.Add(new MenuPageItem() { Title = "Setting", IconSource = "setting.png", TargetType = typeof(Page2) });
MenuList.Add(new MenuPageItem() { Title = "Help", IconSource = "help.png", TargetType = typeof(Page3) });
}
}
My Base View Model Class:
public class BaseVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
And finally the MasterPageDetail page CS:
public partial class MyMainPage : MasterDetailPage
{
private MyMainPageVM myMainPageVM;
public MyMainPage ()
{
InitializeComponent ();
myMainPageVM = new MyMainPageVM();
this.BindingContext = myMainPageVM
}
}